最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is it possible to send binary data with STOMP over WebSockets using Spring-WebSockets? - Stack Overflow

programmeradmin5浏览0评论

I am able to send and receive JSON with STOMP over WebSockets following spring documentation. However performance is poor at large high rates, so I wish to profile the use of binary messages.

  • Spring-WebSockets 4.0
  • JavaScript client running in Chrome 35
  • stomp.js 1.7.1

Sending

I send messages using SimpMessageTemplate with the necessary broker relay - see spring documentation

@Controller
public class DemoBinaryController {
   @Autowired
   private SimpMessagingtemplate template

   @Scheduled(fixedDelay = 5000)
   public void demo() throws Exception {
      GenericMessage<byte[]> message = new GenericMessage<byte[]>(new byte[]{65,66,67});
      template.send("/app/binarydemo", message);
   }
}

Receiving

A JavaScript client receives data using stomp.js using the standard mechanism.

var subscription = client.subscribe("/app/binarydemo", new function(message) {
   console.log("RX message", typeof message.body, message.body.length);
});

Messages are received, but as Strings, with console output as follows. I'm expecting some raw type, like ArrayBuffer

RX message string  3
RX message string  3

Things I've tried

I realise the T in STOMP stands for Text, however the Spring documentation implies binary messages are possible at least with plain WebSockets, also the stomp specification states

STOMP is text based but also allows for the transmission of binary messages.

  • Debugging the sending code, and it appears to remain as byte [] for as far as I can see
  • Debugging the stomp.js library whilst receiving. The message appears to be a String when received in the underlying ws.onmessage callback (line 243 in stomp-1.7.1.js)
  • Lots of searching - this seems a rare topic with little information
  • Looking at the stomp.js source code. The only reference to binary is ws.binaryType = "arraybuffer".

Update: I've done more debugging on the server side. It seems that org.springframework.web.socket.TextMessage is always used within org.springframework.web.socket.messaging.StompSubProtocolHandler rather than org.springframework.web.socket.BinaryMessage. I've raised a feature request for this SPR-12301

message = MessageBuilder.withPayload(message.getPayload()).setHeaders(headers).build();
byte[] bytes = this.stompEncoder.encode((Message<byte[]>) message);

synchronized(session) {
    session.sendMessage(new TextMessage(new String(bytes, UTF8_CHARSET)));
}

My question

  • Is this approach possible with this mix of technologies?
  • Am I missing some crucial step?
  • Can anyone point me to a working example

I am able to send and receive JSON with STOMP over WebSockets following spring documentation. However performance is poor at large high rates, so I wish to profile the use of binary messages.

  • Spring-WebSockets 4.0
  • JavaScript client running in Chrome 35
  • stomp.js 1.7.1

Sending

I send messages using SimpMessageTemplate with the necessary broker relay - see spring documentation

@Controller
public class DemoBinaryController {
   @Autowired
   private SimpMessagingtemplate template

   @Scheduled(fixedDelay = 5000)
   public void demo() throws Exception {
      GenericMessage<byte[]> message = new GenericMessage<byte[]>(new byte[]{65,66,67});
      template.send("/app/binarydemo", message);
   }
}

Receiving

A JavaScript client receives data using stomp.js using the standard mechanism.

var subscription = client.subscribe("/app/binarydemo", new function(message) {
   console.log("RX message", typeof message.body, message.body.length);
});

Messages are received, but as Strings, with console output as follows. I'm expecting some raw type, like ArrayBuffer

RX message string  3
RX message string  3

Things I've tried

I realise the T in STOMP stands for Text, however the Spring documentation implies binary messages are possible at least with plain WebSockets, also the stomp specification states

STOMP is text based but also allows for the transmission of binary messages.

  • Debugging the sending code, and it appears to remain as byte [] for as far as I can see
  • Debugging the stomp.js library whilst receiving. The message appears to be a String when received in the underlying ws.onmessage callback (line 243 in stomp-1.7.1.js)
  • Lots of searching - this seems a rare topic with little information
  • Looking at the stomp.js source code. The only reference to binary is ws.binaryType = "arraybuffer".

Update: I've done more debugging on the server side. It seems that org.springframework.web.socket.TextMessage is always used within org.springframework.web.socket.messaging.StompSubProtocolHandler rather than org.springframework.web.socket.BinaryMessage. I've raised a feature request for this SPR-12301

message = MessageBuilder.withPayload(message.getPayload()).setHeaders(headers).build();
byte[] bytes = this.stompEncoder.encode((Message<byte[]>) message);

synchronized(session) {
    session.sendMessage(new TextMessage(new String(bytes, UTF8_CHARSET)));
}

My question

  • Is this approach possible with this mix of technologies?
  • Am I missing some crucial step?
  • Can anyone point me to a working example
Share Improve this question edited Oct 6, 2014 at 12:20 Adam asked Oct 6, 2014 at 9:55 AdamAdam 36.7k9 gold badges103 silver badges144 bronze badges 2
  • Can you post the Stomp frame headers? – mjn Commented Oct 20, 2014 at 16:44
  • Which message broker is it? – mjn Commented Oct 20, 2014 at 16:44
Add a comment  | 

2 Answers 2

Reset to default 15

It seems that org.springframework.web.socket.TextMessage is always used within org.springframework.web.socket.messaging.StompSubProtocolHandler rather than org.springframework.web.socket.BinaryMessage. I've raised a feature request for this SPR-12301 which has been accepted.

message = MessageBuilder.withPayload(message.getPayload()).setHeaders(headers).build();
byte[] bytes = this.stompEncoder.encode((Message<byte[]>) message);

synchronized(session) {
    session.sendMessage(new TextMessage(new String(bytes, UTF8_CHARSET)));
}

Update

  • SPR-12301 was delivered in 4.1.2 but only adds support for receiving binary messages
  • Raised SPR-12475 for sending of binary messages

Try to configure you Server just with ByteArrayMessageConverter:

@Configuration
@EnableWebSocketMessageBroker
public class MyWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
   
   @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
        messageConverters.add(new ByteArrayMessageConverter());
        return false;
    }

}

UPDATE

Ah! I see that. Thanks:

public TextMessage(byte[] payload) {
    super(new String(payload, UTF_8));
    this.bytes = payload;
}

From other side from STOMP spec:

The body of a STOMP message must be a String. If you want to send and receive JSON objects, ...

According to the ArrayBuffer:

Getting an array buffer from existing data

  • From a Base64 string
  • From a local file

So, I think you don't have a chioce rather than provide you some custom MessageConverter, which converts your byte[] to Base64 String and send it.

On the JavaScript side you should decode that string to the ArrayBuffer somehow.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论