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

I can catch CONNECT command in MyChannelInterceptor, in postSend method - OK 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):

I CAN'T catch CONNECT command in MyChannelInterceptor, in postSend method - CRITICAL 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

Comment From: rstoyanchev

The behavior for DISCONNECT is expected. It is mentioned in several places, under Interception, Events, and Monitoring.

The behavior for CONNECT, however, is not what I would expect. STOMP sits on top of WebSocket and SockJS and every frame goes into the clientInboundChannel, regardless of the underlying transport and without the broker seeing the CONNECT, the connection wouldn't work. Is this easily reproducible with the sample? If not could you please provide something.

Comment From: rstoyanchev

Also have you seen the sections on Authentication and Token Authentication. The latter includes a sample as well using preSend, and not postSend. The latter is not invoked if for some reason the message is not sent.

Comment From: DruidKuma

Hi @rstoyanchev Thanks for the attention to this issue. I'll definitely review the sections you've mentioned, regarding preSend for Auth and DISCONNECT behaviour. Regarding your question on the CONNECT issue - it is quite simple to reproduce. Basically, I just did the following: 1) Cloned the example repo: https://github.com/spring-guides/gs-messaging-stomp-websocket.git 2) Added custom ChannelInterceptor as described in my original post. 3) Put breakpoints in both preSend and postSend methods inside interceptor. 4) Tried connecting with sockJS and directly to WebSocket. If still unclear, I can create sample repository, reproducing the issue, and post here the link

Comment From: rstoyanchev

I cannot reproduce it. I see CONNECT in both cases. For connecting "directly via WebSocket" I change the following line to:

var socket = new WebSocket('ws://localhost:8080/gs-guide-websocket/websocket');

Comment From: DruidKuma

@rstoyanchev This way it works for me too. But the matter is you are still connecting from a browser page. I was trying to connect from mobile client (iOS) when I first experienced this issue. Then, while debugging, I was trying to connect via Chrome Simple WebSocket Client. Could you please try connecting with it?

Comment From: rstoyanchev

was trying to connect via Chrome Simple WebSocket Client. Could you please try connecting with it?

If you could provide more specific instructions. I am not familiar with this client and a quick search isn't very helpful.

Comment From: DruidKuma

Let's keep it as simple, as possible: 1) Go to https://postwoman.io/realtime 2) Enter ws://localhost:8080/gs-guide-websocket/websocket in the URL field 3) Press Connect button When I did same steps, I see no CONNECT

Comment From: rstoyanchev

Press Connect button

I don't see why you expect to see a STOMP CONNECT in this case. Pressing the Connect button here only establishes a raw WebSocket connection. STOMP is a messaging protocol layered on top of WebSocket so you need a STOMP client that's using WebSocket (or SockJS) as a transport.

Comment From: DruidKuma

@rstoyanchev Oh, I see. Looks like I was a bit confused. Sorry, that's not bug, just my fault. Closing the issue.