Spring Websocket ChannelInterceptor 不触发 CONNECT 事件 [英] Spring Websocket ChannelInterceptor not firing CONNECT event

查看:72
本文介绍了Spring Websocket ChannelInterceptor 不触发 CONNECT 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用 Spring 编写简单的 Stomp Websocket 应用程序,客户端都是 web (JS) 和 Mobile (ios, android).从 JS 代码客户端通过 SockJS 连接,而移动客户端在 SockJS 后面使用普通的 websocket 连接.问题是我正在检查身份验证的 ChannelInterceptor 中的行为对于不同类型的连接完全不同.我不能让它对每个客户都一样.让我简单地给出它背后的一些代码并举例说明:Websocket starter 取自 Spring 示例:https://github.com/spring-guides/gs-messaging-stomp-websocket.git

I'm writing simple Stomp Websocket application with Spring, and clients are both web (JS), and Mobile (ios, android). From JS code client connecting over SockJS, while mobile clients are using plain websocket connection behind SockJS. The issue is that behaviour in my ChannelInterceptor where I'm checking authentication, is completely different for different type of connections. I can't make it work the same for every client. Let me briefly give some code behind it and explain by example: Websocket starter was taken from Spring example here: https://github.com/spring-guides/gs-messaging-stomp-websocket.git

Websocket 配置:

Websocket Config:

@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 完成剩下的工作):

When I'm connecting via SockJS from JS app (http://localhost:8080/gs-guide-websocket - and let Spring SockJS do the rest):

  1. 我可以在 MyChannelInterceptor 中捕获 CONNECT 命令,在 postSend 方法中 - OK
  2. 当我关闭连接时,在同一个地方 DISCONNECT 命令会触发两次.- 不好
  1. I can catch CONNECT command in MyChannelInterceptor, in postSend method - OK
  2. When I close the connection, in the same place DISCONNECT command fires TWICE. - Not OK

当我通过 SockJS 后面的 Websocket 连接时 (ws://localhost:8080/gs-guide-websocket/websocket):

When I'm connecting via Websocket behind SockJS (ws://localhost:8080/gs-guide-websocket/websocket):

  1. 我无法在 MyChannelInterceptor 中捕获 CONNECT 命令,在 postSend 方法中 - CRITICAL
  2. 当我关闭连接时,DISCONNECT 命令会正确触发一次.- 好的
  1. I CAN'T catch CONNECT command in MyChannelInterceptor, in postSend method - CRITICAL
  2. When I close the connection, DISCONNECT command fires correctly, once. - OK

基本上,虽然我不明白为什么 sockjs 尝试断开两次连接,但我可以忍受.但是拦截器无法捕获每个连接事件 - 我无法生存,因为我将跟踪用户会话,并从该拦截器准确存储它们.

Basically, though I can't understand why sockjs tries to disconnect twice, I can live with it. But with interceptor not catching every connect event - I can't live, since I'm going to keep track of user session, and store them from exactly that interceptor.

  • 我已经尝试在配置中删除 .withSockJs() - 并且只是连接到套接字 - 同样的问题
  • 我还尝试在 SessionConnectEventSessionConnectedEvent 上实现应用程序事件侦听器 - 同样的问题
  • I've already tried to remove .withSockJs() in the config - and just connect to socket - same problem
  • I've also tried to implement application event listener on SessionConnectEvent and SessionConnectedEvent - same problem

现在我完全被困住了,不知道我还能从这里去哪里......感谢任何帮助或起点.

Now I'm completely stuck and don't know where else I can go from here... Any help or starting point is appreciated.

非常感谢您关注我的痛苦=(

Thanks a lot for any attention to my pain =(

推荐答案

在向 Spring Github 发布问题并在那里进行对话后,我发现这不是错误,基本上不是问题,而只是我的错:

After posting an issue to Spring Github and conversating there, I found out that this is not a bug, and basically not an issue, but just my fault:

  • DISCONNECT 的行为是预期的.它在 Spring WebSocket 文档的 Interception、Events 和 Monitoring 章节中的多个地方都有提及.
  • 通过普通 Websocket 连接时不会触发 CONNECT 事件,因为它只是通过普通 WebSocket 协议建立连接,而对于 STOMP 事件,您需要使用 STOMP 客户端.

有兴趣的可以参考对应的线程:https://github.com/spring-projects/spring-framework/issues/24269

For those interested, please refer to the corresponding thread: https://github.com/spring-projects/spring-framework/issues/24269

这篇关于Spring Websocket ChannelInterceptor 不触发 CONNECT 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆