16

I am trying to create an websocket endpoint with spring. But Whenever I am trying to connect from the client end, I get 404. I also have an Java implementation with

@ServerEndpoint(value = "/websocket")

which works good. Below is the code of my spring implementation which is not working. What am I doing wrong here?

package com.tlab.endpoint;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(socketHandler(),"/socket");;
    }

    @Bean
    public WebSocketHandler socketHandler() {
        return new SocketHandler();
    }

}

below is the Handler

package com.tlab.endpoint;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;


public class SocketHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {

    }

}

In the client side code I tried all diff possible combination

with /socket in handler

var websocket = new WebSocket("ws://localhost:8080/tsim/socket");
var websocket = new WebSocket("ws://localhost:8080/tsim/socket");
var websocket = new WebSocket("ws://localhost:8080/tsim/rest/socket");

with /rest/socket in handler

var websocket = new WebSocket("ws://localhost:8080/tsim/rest/socket");

where tsim is my contextroot. Everything throws the below error

WebSocket connection to 'ws://localhost:8080/tsim/socket' failed: Error during WebSocket handshake: Unexpected response code: 404.

I didn't get any compilation and deployment errors. I used tomcat 8.0 and below is the dispatcher servlet configuration.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:int-ftp="http://www.springframework.org/schema/integration/ftp"
       xmlns:batch="http://www.springframework.org/schema/batch"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.2.xsd
            http://www.springframework.org/schema/integration/ftp http://www.springframework.org/schema/integration/ftp/spring-integration-ftp.xsd
            http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
            http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd"
        >

    <import resource="classpath*:web-db-spring.xml"/>

     <context:component-scan base-package="com.traderslab.nseb,com.tlab.endpoint"/>

     <aop:aspectj-autoproxy/>

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="prefixJson" value="false"/>
                <property name="supportedMediaTypes" value="application/json"/>
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="serializationInclusion" value="NON_NULL"/>
                    </bean>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <mvc:default-servlet-handler/>

</beans>

below is my web.xml

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/classes/dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/rest/</url-pattern>
</servlet-mapping>
buer
  • 330
  • 4
  • 11
anandaravindan
  • 2,401
  • 6
  • 25
  • 35
  • You show `ws://localhost:8080/tsim/socket` in your examples but the error message shows `ws://localhost:8080/TradeSim/socket`. It's `tsim` or `TradeSim`? – Bogdan Jan 17 '15 at 18:23
  • I tried differently.. that part I covered take it as tsim or TradeSim its the contextroot.. To avoid confusion I'll edit it – anandaravindan Jan 17 '15 at 18:41

2 Answers2

4

I finally found the answer myself. Since this is handled by dispatcher servlet as normal http request. I need to add @Controller annotation to the WebSocketConfig class

@Configuration
@EnableWebSocket
@Controller
public class WebSocketConfig implements WebSocketConfigurer
anandaravindan
  • 2,401
  • 6
  • 25
  • 35
  • 1
    I'm using spring boot and have the same problem, however adding @Controller to WebSocketConfig doesn't help. I'm getting a 403 surprisingly. Can you help? – Greyshack Dec 13 '15 at 00:54
  • Found a fix. If you want to test the websocket with your browser you need to add registry.addHandler(socketHandler(),"/socket").setAllowedOrigins("*"); – Greyshack Dec 13 '15 at 10:07
  • Please briefly explaiin or edit your code where to use this registry.addHandler(socketHandler(),"/socket").setAllowedOrigins("*") – susan097 Aug 01 '18 at 12:35
  • @Greyshack this is only the case if your client is running from a different domain to your server. For example, if your client is running at localhost:3000 and your spring server is on localhost:8080, you need it, but not if your spring server is serving the client – Jordan Mackie Sep 20 '19 at 23:18
  • 3
    This smells wrong. How is WebSocketConfig a request handler? Which is what @Controller means. You now have a bean that is both the Controller stereotype and Configuration stereotype. – NealeU Apr 22 '21 at 15:58
0

I my case, the problem was in dispatcher servlet mapping. I had a *.mvc mapping only, and websocket was without it, so I had to change to:

  <servlet-mapping>
     <servlet-name>dispatcherServlet</servlet-name>
     <url-pattern>*.mvc</url-pattern>
     <url-pattern>/</url-pattern>
  </servlet-mapping>
Krystian
  • 2,221
  • 1
  • 26
  • 41