问题
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 inMyChannelInterceptor
, inpostSend
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 inMyChannelInterceptor
, inpostSend
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
andSessionConnectedEvent
- 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 =(
回答1:
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
来源:https://stackoverflow.com/questions/59470938/spring-websocket-channelinterceptor-not-firing-connect-event