41

Is there a way to use WebSockets with SockJS client and Spring 4 server but not using STOMP?

Based on this tutorial from Spring's website, I know how to set up a WebSocket based application using Stomp and Spring 4. On the client side, we have:

 var socket = new SockJS('/hello'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/greetings', function(greeting){ showGreeting(JSON.parse(greeting.body).content); }); }); 

And on the server side, we have the following in the controller:

@MessageMapping("/hello") @SendTo("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(3000); // simulated delay return new Greeting("Hello, " + message.getName() + "!"); } 

Now, I understand that @MessageMapping("/hello") ensures that if a message is sent to a destination "/hello", then the greeting() method will be called. And since the stompClient is subscribed to "/topic/greetings", the @SendTo("/topic/greetings") will send the message back to the stompClient.

But the problem with the above is that stompClient is a Stomp object. And I want to simply use sock.send('test'); and have it delivered to my server's destination. And I want to do @SendTo("myownclientdestinationmap"), I can receive it by

sock.onmessage = function(e) { console.log('message', e.data); }; 

So, any way to do this with Spring 4, SockJS and without Stomp? Or does Spring 4 WebSocket only supports Stomp?

1
  • I want to use WebSocket in my spring-mvc application, could you please guide/tell me why you don't want to use STOMP ?, thank you !!! Commented Nov 24, 2017 at 7:59

1 Answer 1

65

Spring supports STOMP over WebSocket but the use of a subprotocol is not mandatory, you can deal with the raw websocket. When using a raw websocket, the message sent lacks of information to make Spring route it to a specific message handler method (we don't have any messaging protocol), so instead of annotating your controller, you'll have to implement a WebSocketHandler:

public class GreetingHandler extends TextWebSocketHandler { @Override public void handleTextMessage(WebSocketSession session, TextMessage message) { Thread.sleep(3000); // simulated delay TextMessage msg = new TextMessage("Hello, " + message.getPayload() + "!"); session.sendMessage(msg); } } 

And then add your handler to the registry in the configuration (you can add more than one handler and use SockJS for fallback options):

@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(greetingHandler(), "/greeting").withSockJS(); } @Bean public WebSocketHandler greetingHandler() { return new GreetingHandler(); } } 

The client side will be something like this:

var sock = new SockJS('http://localhost:8080/greeting'); sock.onmessage = function(e) { console.log('message', e.data); } 
Sign up to request clarification or add additional context in comments.

7 Comments

hello @Sergi Almar ,I have one question here ,using spring 4 is it possible to connect to web socket using new WebSocket('ws://localhost:8080/my-app/ws-connect-url');?
Sure, just remove the .withSockJS(); from the configuration and use the plain JS WebSocket API (you won't have any fallback options)
This answer works great, but I now I wonder: is it possible in this setup to broadcast a message to all connected clients? It is straightforward in plain JSR356 websockets, so I hope it is doable here too.
Created a separate question from my last comment: stackoverflow.com/q/33910639/4358405
It doesn't work for me using it without .withSockJS() -> can't connect using "ws://localhost....", could you help? I'm using spring boot
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.