Spring-Boot / Websocket Example
It’s been a while!
Project for this post: https://github.com/mtrojahn/spring-boot-websocket
Recently I stumbled upon the need of using Websockets. I confess I know little about the subject and I hope this little tutorial can help you to get started. I’m making this post just because I tried to help here on StackOverflow and I thought I should just post it here as well.
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.marcelustrojahn</groupId> <artifactId>spring-boot-websocket-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-websocket-example</name> <description>Simple Websocket Example</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>org.webjars.bower</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.4</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> <version>1.5</version> <executions> <execution> <goals> <goal>addSources</goal> <goal>addTestSources</goal> <goal>generateStubs</goal> <goal>compile</goal> <goal>testGenerateStubs</goal> <goal>testCompile</goal> <goal>removeStubs</goal> <goal>removeTestStubs</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Application.class (nothing special here)
package com.marcelustrojahn import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication @SpringBootApplication class Application { static void main(String[] args) { SpringApplication.run Application, args } }
WebSocketConfiguration.class
package com.marcelustrojahn import org.springframework.context.annotation.Configuration import org.springframework.messaging.simp.config.MessageBrokerRegistry import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker import org.springframework.web.socket.config.annotation.StompEndpointRegistry @Configuration @EnableWebSocketMessageBroker class WebSocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer { void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic") config.setApplicationDestinationPrefixes("/app") } @Override void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/websocket").withSockJS() } }
PingPongController.class
package com.marcelustrojahn import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.handler.annotation.MessageMapping import org.springframework.messaging.handler.annotation.SendTo import org.springframework.messaging.simp.SimpMessagingTemplate import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Controller @Controller @EnableScheduling class PingPongController { @Autowired SimpMessagingTemplate template @Scheduled(fixedDelay = 20000L) @SendTo("/topic/pingpong") def sendPong() { template.convertAndSend("/topic/pingpong", "pong (periodic)") } @MessageMapping("/ping") @SendTo("/topic/pingpong") def sendPingResponse() { "pong (response)" } }
This is the main thing. For this example I added a scheduled method that will periodically broadcast a message to all clients and another method that will just respond if a client send a “/ping” command.
Now, for the client I have this simple script:
index.html
<!DOCTYPE html> <html> <head> <script src="webjars/sockjs-client/1.0.2/sockjs.js"></script> <script src="webjars/stomp-websocket/2.3.4/lib/stomp.js"></script> <script src="webjars/jquery/3.1.0/jquery.js"></script> </head> <body> <button id="connect">Connect</button> <br> <button id="ping">Send Ping</button> <br> <button id="disconnect">Disconnect</button> <script> var stompClient = { client: null, socket: null, connect: function () { this.socket = new SockJS('/websocket'); this.client = Stomp.over(this.socket); // this.client.debug = null; this.client.connect({}, function (frame) { stompClient.client.subscribe('/topic/pingpong', function (events) { stompClient.consume(events); }); }); }, consume: function (raw) { console.log(raw); }, close: function () { if (this.client != null && this.client != undefined) { this.client.unsubscribe('/topic/pingpong'); this.client.disconnect(); this.client = null; } } }; $("#ping").click(function() { stompClient.client.send("/app/ping", {}, ""); }) $("#disconnect").click(function() { stompClient.close(); }); $("#connect").click(function() { stompClient.connect(); }); </script> </body> </html>
See you next time (and I hope I have more time to explain things).
you could at least finish the example
Thanks for your reply but I’m not sure what you mean. The example is fully functional. The button “Send Ping” sends the websocket command to the server and the result is logged on the console. You can download the full project from the Github repository listed on the post.