====== Basic Websocket ====== This is going to build a STOMP based websocket on server site. - Add dependency to POM.XML - Add a EnableWebSocketMessageBroker configuration - Add a controller to handle the web socket package. ===== Add dependency to POM.XML ===== Add the following in POM.XML org.springframework.boot spring-boot-starter-websocket ===== EnableWebSocketMessageBroker ===== Create a java class that @Configuration and @EnableWebSocketMessageBroker. Here we register an endpoint ''/my-websocket-endpoint'' for frontend to connect to. We add the prefix ''/app'' as application destination prefix so that when the client send their request, they need to add it in their destination. And we have add a channel ''topic'' for client to subscribe. import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/my-websocket-endpoint").withSockJS(); } } ===== Controller to Send and Receive ===== We user @MessageMapping to get the client request, and @SendToUser to send respond back to the requested client, or @SendTo to respond to all clients that subscribe to the channel. The server can also send package to the client by using SimpMessagingTemplate. @Controller public class GreetingController { private final SimpMessagingTemplate simpMessagingTemplate; public GreetingController(SimpMessagingTemplate simpMessagingTemplate) { this.simpMessagingTemplate = simpMessagingTemplate; } @MessageMapping("/hello") @SendToUser("/topic/greetings") public Greeting greeting(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); } @MessageMapping("/helloToAll") @SendTo("/topic/greetings") public Greeting greetingToAll(HelloMessage message) throws Exception { Thread.sleep(1000); // simulated delay return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!"); } public void broadcastNews() { this.simpMessagingTemplate.convertAndSend("/topic/news", new Greeting("This is a news broadcast")); } } ===== JavaScript client ===== First import sockjs, and stomp.js library. ==== Connect to server ==== function connect() { var socket = new SockJS('/my-websocket-endpoint'); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/user/topic/greetings', function (greeting) { console.log(JSON.parse(greeting.body).content); }); stompClient.subscribe('/topic/greetings', function (greeting) { console.log(JSON.parse(greeting.body).content); }); stompClient.subscribe('/topic/news', function (greeting) { console.log(JSON.parse(greeting.body).content); }); }); } ==== To Disconnect ==== function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } ==== To Send ==== We have mapped ''/hello'' to one of our method in the controller. Since we set ''/app'' as prefix, we need to do the following: stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()})); ==== To Receive ==== We have already setup those callback functions while we subscribe the channels during the connection. ===== Notes ===== * The websocket has a default 25 second keep-a-live package. * The socket will auto disconnect when the browser/tab is closed.