Spring Websocket ChannelInterceptor 未触发 CONNECT 事件
Posted
技术标签:
【中文标题】Spring Websocket ChannelInterceptor 未触发 CONNECT 事件【英文标题】:Spring Websocket ChannelInterceptor not firing CONNECT event 【发布时间】:2020-04-15 15:56:32 【问题描述】:我正在用 Spring 编写简单的 Stomp Websocket 应用程序,客户端既是 web (JS),又是移动 (ios、android)。从通过 SockJS 连接的 JS 代码客户端,而移动客户端在 SockJS 后面使用普通的 websocket 连接。
问题是我正在检查身份验证的ChannelInterceptor
中的行为对于不同类型的连接完全不同。我不能让它对每个客户都一样。
让我简单地给出一些它背后的代码并举例说明:
Websocket starter 取自 Spring 示例:https://github.com/spring-guides/gs-messaging-stomp-websocket.git
Websocket 配置:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
registry.addEndpoint("/gs-guide-websocket")
.setAllowedOrigins("*")
.withSockJS();
@Override
public void configureClientInboundChannel(ChannelRegistration registration)
registration.interceptors(new MyChannelInterceptor());
还有ChannelInterceptor
本身:
public class MyChannelInterceptor implements ChannelInterceptor
@Override
public void postSend(Message<?> message, MessageChannel channel, boolean sent)
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
StompCommand command = accessor.getCommand();
...
当我从 JS 应用程序通过 SockJS 连接时(http://localhost:8080/gs-guide-websocket - 让 Spring SockJS 完成剩下的工作):
-
我可以在
MyChannelInterceptor
中捕获CONNECT
命令,在postSend
方法中 - 好的
当我关闭连接时,在同一个地方DISCONNECT
命令会触发两次。 - 不行
当我通过 SockJS 后面的 Websocket 连接时 (ws://localhost:8080/gs-guide-websocket/websocket):
-
我无法在
MyChannelInterceptor
、postSend
方法中捕获 CONNECT
命令 - 严重
当我关闭连接时,DISCONNECT
命令会正确触发一次。 - 好的
基本上,虽然我不明白为什么 sockjs 会尝试断开两次连接,但我可以忍受。 但是拦截器无法捕获每个连接事件 - 我无法生存,因为我要跟踪用户会话,并将它们从那个拦截器中存储。
我已经尝试在配置中删除.withSockJs()
- 并且只是连接到套接字 - 同样的问题
我还尝试在 SessionConnectEvent
和 SessionConnectedEvent
上实现应用程序事件侦听器 - 同样的问题
现在我完全被困住了,不知道我还能去哪里...... 感谢任何帮助或起点。
非常感谢您对我的痛苦的关注=(
【问题讨论】:
【参考方案1】:在Spring Github上发布问题并在那里交谈后,我发现这不是错误,基本上不是问题,而是我的错:
DISCONNECT 的行为是预期的。在 Spring WebSocket 文档的 Interception、Events 和 Monitoring 章节中的多个地方都提到了它。 通过普通 Websocket 连接时,预计不会触发 CONNECT 事件,因为它只是通过普通 WebSocket 协议建立连接,对于 STOMP 事件,您需要使用 STOMP 客户端。有兴趣的可以参考对应的帖子: https://github.com/spring-projects/spring-framework/issues/24269
【讨论】:
以上是关于Spring Websocket ChannelInterceptor 未触发 CONNECT 事件的主要内容,如果未能解决你的问题,请参考以下文章