0

I have implemented websocket in spring but the JavaScript client cannot connect to the websocket.

Here is the WebSocketConfig class:

package com.myapp.spring.security.config;
import com.myapp.spring.web.controller.MyWebSocketHandler;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.PerConnectionWebSocketHandler;

@Configuration
@EnableWebMvc
@EnableWebSocket
@ComponentScan(basePackages={"com.myapp.spring.*"})
public class WebSocketConfig implements WebSocketConfigurer {

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry
                .addHandler(myWebSocketHandler(), "/endpoint")
                .setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler myWebSocketHandler() {
        return new PerConnectionWebSocketHandler(MyWebSocketHandler.class);
    }


}

Here is the test.html page that tries to connect to the websocket:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">

      <body>

        <p>Going to connect to the WebSocket at /endpoint. Check Console</p>
        <button onclick="ss()">Send</button>
      </body>

      <script type="text/javascript">
        var webSocket = new WebSocket("wss://"+document.location.hostname+":8443"+"/endpoint");
        webSocket.onopen = function(message) {
                processOpen(message);
            };
            webSocket.onmessage = function(message) {
                processMessage(message);
            };
            webSocket.onclose = function(message) {
                processClose(message);
            };
            webSocket.onerror = function(message) {
                processError(message);
            };


            function processOpen(message) {
                console.log("JS: Server Connected... "+message);
            }
            function processMessage(message) {
                console.log("Getting a mess: "+message);
            }
            function processClose(message) {
                console.log("JS: Client disconnected... "+message);
            }
            function processError(message) { //
                console.log("Error occured: "+message);
            }

            function ss() {
                webSocket.send("test");
            }
      </script>

</html>

I initialized the websocket path to be at /endpoint. This is evident by my server logs which say that this has occurred:

[org.springframework.web.socket.server.support.WebSocketHandlerMapping] (ServerService Thread Pool -- 75) Mapped URL path [/endpoint] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]

When I open up test.html, the connection opens and immediately disconnects. The processOpen(message) and processClose(message) function are immediately called, one after the other. So what am I doing wrong, and how can I fix this?

user5139637
  • 775
  • 3
  • 10
  • 29

1 Answers1

0

Your java-script code in test.html looks fine. There could be some issue with Spring Web socket configuration which is closing the connection. Following is the working code for web socket with spring boot. Please compare with your configuration.

Web socket dependency in pom.xml

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

WebSocketHandler class

@Component
public class EchoHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
    TextMessage echoMessage = new TextMessage("Echo :" + message.getPayload());
    System.out.println("Sending "+echoMessage.getPayload());
    session.sendMessage(echoMessage);
  }
}

WebSocket Controller class

@EnableWebSocket
@Controller
public class WSController implements WebSocketConfigurer {
@Autowired
private EchoHandler echoHandler;

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(echoHandler, "/echo").setAllowedOrigins("*"); 
   }
}

Spring Boot application class

@SpringBootApplication
public class WSApplication {

public static void main(String[] args) {
    SpringApplication.run(WSApplication.class, args);
  }
}
abaghel
  • 14,783
  • 2
  • 50
  • 66
  • This didn't't work. I received an error (something that said that a bean was required) in the WebSocketConfig – user5139637 Sep 27 '16 at 03:49
  • Can you please show the exact error message and your updated classes? The code I posted is working fine for me. – abaghel Sep 27 '16 at 03:59
  • I definitely can and will. But I realized after posting this question that my question about web sockets is slightly different. I made another SO post: http://stackoverflow.com/questions/39683062/enable-cors-for-websockets-in-spring If you could help in that, it would be awesome. Thank you so much – user5139637 Sep 27 '16 at 04:01