6

Trying to use Spring 4 WebSocket with STOMP over socket using sockjs. And i faced a problem.

My configuration:

websocket.xml - part of spring context

<websocket:message-broker application-destination-prefix="/app">  
    <websocket:stomp-endpoint path="/ws">                         
        <websocket:sockjs/>                                       
    </websocket:stomp-endpoint>                                   
    <websocket:simple-broker prefix="/topic"/>                    
</websocket:message-broker>       

Controller code:

@MessageMapping("/ws")
@SendTo("/topic/ws")
public AjaxResponse hello() throws Exception {
    AjaxResponse ajaxResponse = new AjaxResponse();
    ajaxResponse.setSuccess(true);
    ajaxResponse.addSuccessMessage("WEB SOCKET!!! HELL YEAH!");
    return ajaxResponse;
}

Client side:

var socket = new SockJS("<c:url value='/ws'/>");               
var stompClient = Stomp.over(socket);                             
stompClient.connect({}, function(frame) {                         
    alert('Connected: ' + frame);                                 
    stompClient.send("/app/ws", {}, {});                       
    stompClient.subscribe('/topic/ws', function(response){ 
        alert(response.success);                                  
    });                                                           
});                                                               

Output:

Opening Web Socket... stomp.js:130
GET http://localhost:8080/ws/info 404 (Not Found) sockjs-0.3.js:807
Whoops! Lost connection to undefined stomp.js:130

What i do wrong?

I've found examples in google (TickerStocks or something like that, greeting applications (example of Spring)) and all of them give me the same error. I trying use WebSocket with handshake (without sockjs) - same result).

ADDITION INFORMATION:

Method public AjaxResponse hello(); placed in IndexController on root context "/". So i can provide full path: http://localhost:8080/ws. To deploy tested tomcat7 and tomcat8.

dikkini
  • 1,184
  • 1
  • 23
  • 52
  • Not really relevant but I would **strongly** suggest you abandon the use of XML based config files and adopt JavaConfig globally rather than mixing and matching. [There is a complete tutorial](http://spring.io/guides/gs/messaging-stomp-websocket/) on setting this up using JavaConfig and sockjs. More significantly, how is your app deployed? It is at the root of the webserver? because your URL in the Javascript is absolute. – Boris the Spider Mar 18 '14 at 13:51
  • May i completely remove ALL xml config from my application? It wont decrease speed of my application? I can remove all XML and create one WebConfig for the whole application? This complete tutorial it is greeting app (example by Spring) which i mention in question, that i tried it. – dikkini Mar 18 '14 at 14:01
  • Yes, you do not need _any_ xml at all. It will definitely not slow down the application - it may even speed it up as your XML doesn't need to be "compiled" into configuration code. You just need to make sure to [bootstrap your application](http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Configuration.html) with the root configuration class. – Boris the Spider Mar 18 '14 at 14:03
  • Boris the Spider, write an answer about remove ALL xml (include web.xml - make WebInitializer instead) i will mark it as answer. After this, i write code with websocket, sockjs and stomp - and everything working. – dikkini Mar 19 '14 at 18:44

4 Answers4

3

I follow Boris The Spider advice and i started use Java Configuration (AppConfig and WebInit files) instead of XML configuration files. When i finished migration - i tried websockets - and it is works! I thought that the main problem was in XML configuration for WebSocket.

Community
  • 1
  • 1
dikkini
  • 1,184
  • 1
  • 23
  • 52
0

I think your issue can be the same of this one and its accepted answer can apply.

In short: check how you mapped your DispatcherServlet. For your endpoint URL to be http://localhost:8080/ws the DispatcherServlet and your application contexte root should be set as "/".

It should be something like this, in your web.xml:

<servlet>
  <servlet-name>WebSocketDispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
  <servlet-name>WebSocketDispatcher</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

This or you need to include context-root and dispatcher mapping in your end-point URL:

http://<server>:<port>/<context-root>/<dispatcher-mapping>/ws

I hope it can help you.

Regards.

Heleno

Community
  • 1
  • 1
helenov
  • 341
  • 1
  • 2
  • 15
  • i cant check this now, because i have no more xml configuration at my application – dikkini Apr 16 '14 at 17:58
  • @dikkini, just removing xml configuration from you app managed to solve the problem, or had you also fixed DispatcherServlet mapping and/or context root? I'm curious about the solution with WebInitializer. Can't you post it yourself as answer? – helenov Apr 16 '14 at 18:48
0

firstly, you have set destination prefix with app, so you must add 'app' into your request url. e.g. if i wanted to request for '/ws', i should create SockJS with path '/server/app/ws', also you can code with var socket = new SockJS("<c:url value='/server/app/ws'/>") and you know the 'server' is your project name over springmvc.

secondly, you must add the path '/app/*' to org.springframework.web.servlet.DispatcherServlet so as to avoid the path with prefix '/app' intercepted by interceptor defined in web.xml.

Pacoson
  • 1
  • 2
0

I arrived on this page and - thanks to Boris Accepted Answer was motivated to reconsider the java approach as opposed to the xml approach which was causing the - /info=34424 with 404 error...whoops lost connection - I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldung worked(for me without changing from Spring 4.2 to 5 or Boot). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>

Baeldung's implementation curiously does not make any such calls

flow/websocket/add/info?t=1540813753999

What it does (on send and receive) is below. I am only pasting it in case people well-versed with these libraries can further add insights on this forum.

 >>> SEND
destination:/app/chat
content-length:38

{"from":"nicholas","text":"try again"}

<<< MESSAGE
destination:/topic/messages
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:m3p096zk-11
content-length:53

{"from":"nicholas","text":"try again","time":"13:46"}
veritas
  • 378
  • 1
  • 6
  • 16