Search code examples
javaspringwebsocketstompsockjs

Spring Websocket ChannelInterceptor not firing CONNECT event


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

And ChannelInterceptor itself:

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();
        ...
    }
}

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

  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

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

  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

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.

  • 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 =(


Solution

  • 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:

    • The behavior for DISCONNECT is expected. It is mentioned in several places in the Spring WebSocket documentation, under Interception, Events, and Monitoring chapters.
    • CONNECT event is not expected to be fired when connecting via plain Websockets, cause it is just establishing connecting over plain WebSocket protocol, and for STOMP events you need to use STOMP client.

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