Search code examples
javaspringtomcatspring-websocketsockjs

Spring with STOMP over SockJS and Tomcat not upgrading to Websockets


I am building a Stateless Spring (4.2.4.RELEASE) Solution using STOMP over Websockets with SockJS and a Rest Endpoint using JWT to connect mobile devices with Full Duplex communication. I am using Tomcat 8.0.33 as a Web Server and testing using html with sockjs javascript client. The stomp protocol works fine using the http fallback but I can't make it using only a websocket protocol. I tried CORS in many ways but I am not sure that is a Tomcat Problem or just bad spring configuration. I tested my html even in the same domain and port and SockJS is still falling back into xhr or iframes.

WebScoketConfig.java

@EnableWebSocketMessageBroker
 public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
{

@Override
public void registerStompEndpoints(StompEndpointRegistry registry)
{
    RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy();
    registry.addEndpoint("/ws").setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy))
    .setAllowedOrigins("*").withSockJS().setSessionCookieNeeded(false)
    .setStreamBytesLimit(512 * 1024)
    .setHttpMessageCacheSize(1000)
    .setDisconnectDelay(30 * 1000);
}

@Override
public void configureClientOutboundChannel(ChannelRegistration registration) {
    registration.taskExecutor().corePoolSize(50);
}


@Override
public void configureMessageBroker(MessageBrokerRegistry registry)
{
    registry.enableSimpleBroker("/queue/", "/topic/");
    // registry.enableStompBrokerRelay("/queue/", "/topic/");
    registry.setApplicationDestinationPrefixes("/myapp");
}

 public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
    registration.setMessageSizeLimit(500 * 1024);
    registration.setSendBufferSizeLimit(1024 * 1024);
    registration.setSendTimeLimit(20000);
 }
}

WebSecurityConfig.java

    public class WebSecurityConfig extends WebSecurityConfigurerAdapter
    {

        @Override
        protected void configure(HttpSecurity http) throws Exception
        {
            http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/**").permitAll();                
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception
        {

        }
    }

Solution

  • I solved my problem, actually the code was good but the antivirus (Kaspersky) was closing the connection on my client browser just after opened. It forces SockJS to fallback into a different strategy. I tested the client with the antivirus turned off and the Websocket transport was beautifully running. Tested on mac & linux as well.