Algobook
- The developer's handbook
mode-switch
back-button
Buy Me A Coffee
Sat Jan 06 2024

How to add websockets in Java Spring Boot

In the first post of 2024, it's my honor to show you guys how we can setup websockets in our existing Java Spring Boot application, and connect to it from a React application using StompJs. Websockets are amazing, they allow us to create real time web applications with updates happening without any refreshes needed - if you have read my articles before, you know I am a big fan of them.

Here are some previous articles where I've implemented websockets in NodeJs:

For this guide, you need

  • an existing Spring Boot application setup
  • a simple React application
  • a good mood and a cup of coffee

Setup websockets in your Spring Boot application

Let's begin with setting up the websockets on our server. For this, you need to install two dependencies. In Gradle, add them as following:

dependencies { ...otherDeps, implementation 'org.springframework:spring-messaging:6.1.2' implementation 'org.springframework:spring-websocket:6.1.2' }

Find the dependencies here on Maven central:

Add a WebSocketConfig configuration class

Create a class called WebSocketConfig.java and add following code:

package com.example.project; 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("/"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws-endpoint").setAllowedOriginPatterns("*"); } }

In here, we setup the configuration for our websockets. The most important part is the registry.addEndpoint("/ws-endpoint") where we setup the endpoint to connect to our websockets. And with setAllowedOriginPatterns("*") we allow anyone to connect to them, so bear this in mind if you are deploying this to an production environment.

Setup a ping endpoint

Now we will create a simple endpoint that we can use to send messages to, and get a response back from. Create a new class called PingEndpoint.java and add following code:

package com.example.project; import com.example.project.models.Ping; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; @Controller public class PingEndpoint { @MessageMapping("/ping") @SendTo("/topics/pong") public Ping ping(Ping pingBody) { Ping pingResponse = new Ping(); pingResponse.setName("Pong " + pingBody.getName()); return pingResponse; } }

In here, we are telling our websocket server to listen for messages to /app/ping and send the response to subscribers of /topics/pong.

And then create a simple model class for our Ping class.

package com.example.project; import lombok.Getter; import lombok.Setter; @Getter @Setter public class Ping { String name; }

Broadcast with SimpMessagingTemplate

If you have stuff happening on the server side and want to broadcast the result to the listeners every time there are something new to deliver, we can use the SimpMessagingTemplate class for this. This can for example be in use cases where you have a backend connected to a third party vendor that are pushing data to your backend that you want to publish to your clients. Or if you perhaps have some status checks of your services that your backend are constantly checking and want to broadcast the information to the client application - the use cases are many 😃

I will simply show an example class of how this can be achieved.

package com.example.project; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @EnableScheduling @Component public class MyService { private final SimpMessagingTemplate broker; public MyService(@Autowired SimpMessagingTemplate broker) { this.broker = broker; } @Scheduled(fixedDelay = FIVE_MINUTES, initialDelay = 500) public void execute() { // do some task MyHealthStatus healthStatus = new HealthStatus(); broker.convertAndSend("/topic/health-status", healthStatus); } }

So here we imagine that we have a service running every five minutes, and do some health checks on our services - and once it is done, we publish the result to every subscriber of the /topic/health-status topic.

Client side

Now it's time to do some client side programming. Head over to your React application and install stomp js

npm i @stomp/stompjs

and in your component, add following code to setup our subscriber and to publish our ping message.

import React, { useEffect } from "react"; import { Client } from "@stomp/stompjs"; const BASE_URL_WS = "ws://localhost:8080/ws-endpoint"; export const MyComponent = () => { useEffect(() => { fetch(); const client = new Client({ brokerURL: `${BASE_URL_WS}`, onConnect: () => { client.publish({ destination: "/app/ping", body: JSON.stringify({ name: "Christian" }), }); client.subscribe("/topics/pong", (message) => { const body = JSON.parse(message.body); console.log(body); }); }, }); client.activate(); return () => { client.deactivate(); }; }, []); return <div>My component</div>; }; export default MyComponent;

And now when the component is mounted, you should see some messages in the console and in the network tab you should be able to see some websocket events being triggered.

Summary

There we have it. In this short guide, we demonstrated how we can implement websockets in our Spring Boot application, and how we can connect to it using StompJs. We showed both how to send/receive using a Controller, but also how we can broadcast messages using the SimpMessagingTemplate class.

I hope you got it to work, and that it could help you getting started with websockets in your application.

Have an amazing day!

signatureSat Jan 06 2024
See all our articles