3

As per (Is it possible to send binary data with STOMP over WebSockets using Spring-WebSockets?) it appears that it should be possible to send binary messages with STOMP over websockets.

I have configured the WebSocketStompClient as follows:

List<Transport> transports = new ArrayList<>(1);
transports.add(new WebSocketTransport( new StandardWebSocketClient()) );
WebSocketClient transport = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(transport);
// using a custom converter to serialize java object to byte[]
stompClient.setMessageConverter( new SerializedJavaObjectMessageConverter() );

I am using the following to send a message:

StompHeaders stompHeaders = new StompHeaders();
stompHeaders.setDestination( "/app/greetings");
stompHeaders.setContentType( MimeTypeUtils.APPLICATION_OCTET_STREAM );
session.send(stompHeaders, new Greeting( message ));

I receive an exception from the following assertion:

Assert.isInstanceOf(TextMessage.class, message, this + " supports text messages only.");

found in org.springframework.web.socket.sockjs.client.AbstractClientSockJs (below) which only appears to support TextMessage:

@Override
public final void sendMessage(WebSocketMessage<?> message) throws IOException {
    Assert.state(State.OPEN.equals(this.state), this + " is not open, current state=" + this.state);
    Assert.isInstanceOf(TextMessage.class, message, this + " supports text messages only.");
    String payload = ((TextMessage) message).getPayload();
    payload = getMessageCodec().encode(new String[] { payload });
    payload = payload.substring(1); // the client-side doesn't need message framing (letter "a")
    message = new TextMessage(payload);
    if (logger.isTraceEnabled()) {
            logger.trace("Sending message " + message + " in " + this);
    }
    sendInternal((TextMessage) message);
}

Does the new java client WebSocketStompClient (4.2-SNAPSHOT) configured as above (i.e. using SockJS for fallback) support sending binary messages?

UPDATE:

The following client configuration works:

WebSocketClient transport = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(transport)
Community
  • 1
  • 1
stacktrace
  • 547
  • 1
  • 6
  • 19
  • Could you clarify what your question is? – Nic May 27 '15 at 18:28
  • @QPaysTaxes - As per your comment I have reworded the question. – stacktrace May 27 '15 at 19:12
  • As per comment by Rossen Stoyanchev on https://jira.spring.io/browse/SPR-12301, SockJs doesn't support binary messages (https://github.com/sockjs/sockjs-protocol/issues?q=is%3Aopen+is%3Aissue+binary) – stacktrace Jun 01 '15 at 11:16

1 Answers1

1

I was able to get this to work by sending a TextMessage instead. I created another custom MessageConverter that Base64 encodes / decodes the serialized object:

public class Base64JavaObjectMessageConverter extends AbstractMessageConverter {

    public Base64JavaObjectMessageConverter() {
        super(MimeTypeUtils.TEXT_PLAIN);
    }

    @Override
    protected boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    public Object convertFromInternal(Message<?> message, Class<?> targetClass) {
        byte[] messageBytes = Base64.getDecoder().decode( (byte[])message.getPayload() );
        return SerializationUtils.deserialize( messageBytes  );
    }

    @Override
    public Object convertToInternal(Object payload, MessageHeaders headers) {
        byte[] messageBytes = SerializationUtils.serialize( payload );
        return Base64.getEncoder().encode( messageBytes);
    }

}
stacktrace
  • 547
  • 1
  • 6
  • 19