SockJS无序接收弹簧websocket的stomp消息

Zhi*_*hao 8 stomp sockjs spring-websocket

我正在尝试使用Springframework SimpMessagingTemplate(默认的Stomp实现)来传输时间序列数据,以将消息广播到SockJS客户端订阅的主题.但是,消息是无序接收的.服务器是单线程,消息按时间戳按升序发送.客户端以某种方式收到了订单中的消息.

我正在使用stompjs和springframework(4.1.6版本)的最新版本.

Zhi*_*hao 10

找到了这个问题的根本原因.消息从应用程序实现的角度以"正确"的顺序发送(即,在一个线程或至少是线程安全的方式中调用convertAndSend()).但是,Springframework Web套接字使用reactor-tcp实现,它将处理消息来自线程池的clientOutboundChannel.因此消息可以按它们到达的不同顺序写入tcp套接字.当我配置web套接字限制clientOutboundChannel的1个线程时,保留顺序.

这个问题不在SocketJS中,而是当前Spring Web套接字设计的限制.

  • 您如何配置 Web 套接字以限制 clientOutboundChannel 的 1 个线程? (2认同)

小智 9

看起来有一个内置的条纹执行器,所以只需启用它:

@Override
protected void configureMessageBroker(MessageBrokerRegistry registry) {
    // ...
    registry.setPreservePublishOrder(true);
}
Run Code Online (Sandbox Code Playgroud)

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


Daw*_*ert 8

这是Spring Web套接字设计问题.要以有效顺序接收消息,您必须将websocket客户端的corePoolSize设置为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);
    }
}
Run Code Online (Sandbox Code Playgroud)