Java &引用;没有会话id的解码器“;在Spring web套接字和Stomp的日志中

Java &引用;没有会话id的解码器“;在Spring web套接字和Stomp的日志中,java,spring,websocket,stomp,spring-websocket,Java,Spring,Websocket,Stomp,Spring Websocket,我有一个tomcat集群,在一台服务器上有两个实例和apache代理。应用程序使用Spring framework 4.3.10和web套接字,apache-activemq-5.15.0作为stomp代理: <websocket:message-broker application-destination-prefix="/app"> <websocket:stomp-endpoint path="/wshandler" allowed-origins="*">

我有一个tomcat集群,在一台服务器上有两个实例和apache代理。应用程序使用Spring framework 4.3.10和web套接字,apache-activemq-5.15.0作为stomp代理:

<websocket:message-broker application-destination-prefix="/app">
  <websocket:stomp-endpoint path="/wshandler" allowed-origins="*">
  </websocket:stomp-endpoint>
  <websocket:stomp-broker-relay prefix="/topic,/queue"
                                relay-host="localhost" relay-port="62356"
                                heartbeat-send-interval="10000" heartbeat-receive-interval="10000"/>
        <websocket:client-inbound-channel>
            <websocket:interceptors>
                <bean class="somepath.TopicSubscriptionInterceptor"/>
            </websocket:interceptors>
        </websocket:client-inbound-channel>
</websocket:message-broker>

将连接帧中的heartbeat标头更新为50005000,这意味着客户端和服务器都需要每帧5秒发送一次heartbeat帧。在我的例子中,服务器在空闲时间过长时正在断开连接。这样做的实质是保持底层TCP连接处于活动状态,以便服务器不会关闭它。进行此更改后,还要重新启动服务器。 希望这有帮助

如果使用amqp上的java客户端连接到rabbitMq,则可以设置

ConnectionFactory cf = new ConnectionFactory();
// set the heartbeat timeout to 60 seconds
cf.setRequestedHeartbeat(60);
参考资料:


在新的spring框架版本()

如果您使用的是旧版本(2019年之前),则可以通过覆盖WebSocketHandlerDecorator来解决此问题:

@Slf4j
public class WebSocketSessionCapturingHandlerDecorator extends WebSocketHandlerDecorator {

    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
    
        if(session.isOpen()){
            super.handleMessage(session, message);
        }else{
            log.info("Dropped inbound WebSocket message due to closed session");
        }
    
}

在activemq日志中,有以下内容:>>2017-10-07 18:02:40008 |警告|传输连接到:tcp://127.0.0.1:52482 失败:org.apache.activemq.transport.InactivityIOException:通道处于非活动状态的时间太长(>10000):tcp://127.0.0.1:52482 |org.apache.activemq.broker.TransportConnection.Transport | activemq不活动监视器,这是与客户端的会话似乎已关闭的原因,它删除了与会话id关联的解码器;如果在此会话中之后收到任何消息,则会抛出“会话无解码器”。也许您可以尝试增加心跳接收间隔?AMQP发送心跳的频率不够高,Spring relay会断开连接?由于服务器关闭了连接,Spring会断开会话以及与之相关的所有内容(解码器),因此会出现id错误的无解码器。要修复它,您需要确保底层TCP连接始终保持活动状态。您可以通过设置心跳来实现这一点,心跳只是在客户端和服务器之间来回发送的ping,这样可以保持连接处于活动状态。您所需要做的就是将某些头传递给服务器,服务器将完成其余的工作。查看STOMP文档。
@Slf4j
public class WebSocketSessionCapturingHandlerDecorator extends WebSocketHandlerDecorator {

    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
    
        if(session.isOpen()){
            super.handleMessage(session, message);
        }else{
            log.info("Dropped inbound WebSocket message due to closed session");
        }
    
}
@Slf4j
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer  {

  @Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
    registration.addDecoratorFactory(new WebSocketHandlerDecoratorFactory() {
        @Override
        public WebSocketHandler decorate(WebSocketHandler webSocketHandler) {
            return new WebSocketSessionCapturingHandlerDecorator(webSocketHandler);
        }
    });
}