Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SockJS receive stomp messages from spring websocket out of order

I am trying to streaming time series data using Springframework SimpMessagingTemplate (default Stomp implementation) to broadcast messages to a topic that the SockJS client subscribed to. However, the messages is received out of order. The server is single thread and messages are sent in ascending order by their timestamps. The client somehow received the messages out of the order.

I am using the latest release version of both stompjs and springframework (4.1.6 release).

like image 471
Zhichao Avatar asked Apr 17 '15 03:04

Zhichao


People also ask

Is STOMP deprecated?

This project is no longer maintained. If you encounter bugs with it or need enhancements, you can fork it and modify it as the project is under the Apache License 2.0.

Does STOMP use WebSocket?

By default, stomp. js will use the Web browser native WebSocket class to create the WebSocket. However it is possible to use other type of WebSockets by using the Stomp. over(ws) method.

How do I send a message to a specific user WebSocket Spring boot?

These steps need to be performed: Generate a Spring Security Principal name by UUID for each newly connected client by using DefaultHandshakeHandler. Store the UUID if a new message is received. Use @SendToUser instead of @SendTo annotation in the WebSocket controller.


3 Answers

looks like there is a built in striped executor, so just enable it:

@Override
protected void configureMessageBroker(MessageBrokerRegistry registry) {
    // ...
    registry.setPreservePublishOrder(true);
}

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#websocket-stomp-ordered-messages

like image 53
Jason Avatar answered Nov 12 '22 00:11

Jason


It's Spring web socket design problem. To receive messages in valid order you have to set corePoolSize of websocket clients to 1.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfiguration extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(1);
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(1);
    }
}
like image 35
Dawid Kunert Avatar answered Nov 12 '22 00:11

Dawid Kunert


Found the root cause of this issue. The messages were sending in "correct" order from the application implementation perspective (I.e, convertAndSend() are called in one thread or at least thread safe fashion"). However, Springframework web socket uses reactor-tcp implementation which will process the messages on clientOutboundChannel from the thread pool. Thus the messages can be written to the tcp socket in different order that they are arrived. When I configured the web socket to limit 1 thread for the clientOutboundChannel, the order is preserved.

This problem is not in the SocketJS but a limitation of current Spring web socket design.

like image 11
Zhichao Avatar answered Nov 11 '22 22:11

Zhichao