java - Spring web 套接字和 Stomp 日志中的 "No decoder for session id"

标签 java spring websocket stomp spring-websocket

我有一个 tomcat 集群,在一台服务器上有 2 个实例和 apache 代理。应用程序使用带有 web 套接字的 Spring 框架 4.3.10,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>

现在大约有 20 个客户端同时连接到网络套接字。一切正常,但我定期在日志中出现错误(估计一小时内出现 8-10 次)。我该如何解决?

2017-10-06 09:54:01,046 ERROR [StompSubProtocolHandler] Failed to parse TextMessage payload=[], byteCount=1, last=true] in session 6f. Sending STOMP ERROR to client.
java.lang.IllegalStateException: No decoder for session id '6f'
at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageFromClient(StompSubProtocolHandler.java:249)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:307)
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75)
at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56)
at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:110)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:42)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:81)
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:78)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:394)
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82)
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171)
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)

最佳答案

在新的spring框架版本中解决了(https://github.com/spring-projects/spring-framework/commit/f425a993e7be82ffdbdda24370925a34c42925f2)

如果您使用的是旧版本(直到 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");
        }
    
}

并在主 WebSocketConfig 中使用它:

@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);
        }
    });
}

关于java - Spring web 套接字和 Stomp 日志中的 "No decoder for session id",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46603988/

相关文章:

java - contains() 与泛型类型

spring - 可以为Redission配置RedisTemplate吗?

javascript - 为什么我的 websocket php+javascript 代码不起作用?

websocket - 在 Electron 中拦截并回复 WSS 请求

java - 警告 : The type parameter E is hiding the type E when using an inner class

java - Android完全隐藏RelativeLayout

java - 在Ubuntu 12.04上构建openjdk7报错

java - Xa资源恢复管理器 : Error while retrieving xids from resource

spring - <task :annotation-driven> in spring 4. 3 的注释是什么

javascript - 如何通过网络套接字构建 xmpp 网络聊天应用程序,如 gtalk