Often in projects, we need to maintain constant communication with the backend server to make requests or display real-time information. WebSockets can help us with that. In this post, we’ll see how to implement WebSockets with STOMP and Spring Boot through an example.
What is a Socket?
A WebSocket is a bidirectional communication protocol over TCP between the browser and the server. This communication can last as long as the client or server decides until one of them closes it.
The most practical use case is often for chats, where you maintain constant open communication between the browser and the server.
WebSocket Configuration with Spring
Add Maven Dependency
To begin, let’s add the following dependency to our Spring Boot project:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
Activate WebSocket in Spring Boot
In the following code snippet, we’ll activate WebSocket in our Spring Boot application, register the endpoints using the registerStompEndpoints
method, and configure the message broker in the configureMessageBroker
method.
In the registerStompEndpoints
method, all origins have been allowed for testing from any socket client.
@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("/chat"); registry.addEndpoint("/chat").withSockJS(); registry.addEndpoint("/chat").setAllowedOrigins("*"); } }
Create the Message
Next, let’s create the message that we’ll receive, which will have two fields:
@Getter @Setter public class Message { private String text; private String name; }
Create the Message Controller
Once we’ve created the message, we’ll create the controller responsible for receiving the message. For this, we’ll use two Spring annotations: @MessageMapping
and @SendTo
.
@MessageMapping("/status") @SendTo("/topic/messages") public MessageDto sendMessage(MessageDto message, @Header("simpSessionId") String sessionId) { //Do something return new MessageDto("Message with text : " + message.getText() + " received ", " from " + message.getName()); }
The above method will be present in a class annotated with @RestController
or @Controller
. With the @MessageMapping
annotation, it becomes the endpoint that receives the messages and, with the @SendTo
annotation, it sends them to the topic.
One more thing to note is that when we receive a message, we store its sessionId
to know who disconnects. This is done using the simpSessionId
attribute that arrives in the header.
Create Socket Disconnect Notification
Generally, sockets are used to create a communication channel between the browser and the server. Therefore, it’s necessary to know when the socket disconnects, for example, when the browser closes. For this, we’ll use the @EventListener
annotation from Spring. This annotation will be invoked when it receives an event of type SessionDisconnectEvent
.
@EventListener public void onDisconnectEvent(SessionDisconnectEvent event) { log.debug("Client with session id {} disconnected", event.getSessionId()); String sessionId = event.getSessionId(); //Do something }
Conclusion
In this article, we have seen how to configure WebSockets with STOMP and Spring Boot. The focus of this article has been from the server-side perspective. To test the application, you can use a client like AdvancedRestClient.
You can find the complete example on GitHub.
If you need more information, you can leave us a comment or send an email to refactorizando.web@gmail.com You can also contact us through our social media channels on Facebook or twitter and we will be happy to assist you!!
Other interesting post:
Spring Boot Actuator with Grafana and Prometheus
SoftDelete with Spring Boot and Hibernate