DEV Community

FullStackJava
FullStackJava

Posted on

Real-Time Notifications with WebSocket in Spring Boot

In modern web applications, real-time communication between the server and clients is becoming increasingly important. Traditional HTTP request-response communication is not suitable for scenarios where data needs to be pushed from the server to clients in real-time. This is where WebSocket comes into play. WebSocket is a protocol that provides full-duplex communication channels over a single TCP connection, allowing for bi-directional data flow between the server and clients.

Spring Boot provides excellent support for WebSocket through its spring-websocket module. In this blog post, we'll explore how to build a real-time notification system using WebSocket in a Spring Boot application.

Prerequisites

Before we dive in, ensure you have the following:

  • Basic knowledge of Spring Boot and Java
  • Understanding of the WebSocket protocol
  • Familiarity with front-end technologies like JavaScript and HTML

Setting Up the Spring Boot Application

1. Add Dependencies

First, create a new Spring Boot project or add the following dependencies to your existing pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

2. Enable WebSocket Support

Enable WebSocket support by adding the @EnableWebSocketMessageBroker annotation to your main application class or a dedicated configuration class.

Creating the WebSocket Configuration

1. Define WebSocket Configuration

Create a configuration class to set up WebSocket:

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.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("/websocket").withSockJS();
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Explanation

  • @EnableWebSocketMessageBroker enables WebSocket message handling.
  • setApplicationDestinationPrefixes maps incoming messages to @MessageMapping methods.
  • enableSimpleBroker sets up an in-memory message broker.

Implementing the WebSocket Handler

1. Create a Message Controller

Create a controller to handle incoming WebSocket messages:

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class NotificationController {

    @MessageMapping("/send")
    @SendTo("/topic/notifications")
    public String sendNotification(String message) {
        return message;
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Explanation

  • @MessageMapping("/send") maps to /app/send.
  • @SendTo("/topic/notifications") sends the message to /topic/notifications.

Sending Notifications

1. Inject SimpMessagingTemplate

Inject SimpMessagingTemplate to send messages:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

@Service
public class NotificationService {

    @Autowired
    private SimpMessagingTemplate template;

    public void sendNotification(String message) {
        template.convertAndSend("/topic/notifications", message);
    }
}
Enter fullscreen mode Exit fullscreen mode

2. Explanation

  • convertAndSend sends a message to the specified destination.

Building the Front-End

1. Create HTML File

Create an HTML file with a WebSocket connection:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Notifications</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
    <div id="notifications"></div>
    <script>
        var socket = new SockJS('/websocket');
        var stompClient = Stomp.over(socket);

        stompClient.connect({}, function(frame) {
            stompClient.subscribe('/topic/notifications', function(notification) {
                var notifications = document.getElementById('notifications');
                var message = document.createElement('p');
                message.appendChild(document.createTextNode(notification.body));
                notifications.appendChild(message);
            });
        });
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

2. Explanation

  • Connect to the WebSocket endpoint.
  • Subscribe to /topic/notifications.
  • Display received messages in the browser.

Example Implementation

Here is a complete example implementation with the server-side and client-side components we discussed.

Server-Side Code

WebSocketConfig.java

@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("/websocket").withSockJS();
    }
}
Enter fullscreen mode Exit fullscreen mode

NotificationController.java

@Controller
public class NotificationController {

    @MessageMapping("/send")
    @SendTo("/topic/notifications")
    public String sendNotification(String message) {
        return message;
    }
}
Enter fullscreen mode Exit fullscreen mode

NotificationService.java

@Service
public class NotificationService {

    @Autowired
    private SimpMessagingTemplate template;

    public void sendNotification(String message) {
        template.convertAndSend("/topic/notifications", message);
    }
}
Enter fullscreen mode Exit fullscreen mode

Client-Side Code

index.html

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Notifications</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
    <div id="notifications"></div>
    <script>
        var socket = new SockJS('/websocket');
        var stompClient = Stomp.over(socket);

        stompClient.connect({}, function(frame) {
            stompClient.subscribe('/topic/notifications', function(notification) {
                var notifications = document.getElementById('notifications');
                var message = document.createElement('p');
                message.appendChild(document.createTextNode(notification.body));
                notifications.appendChild(message);
            });
        });
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this blog post, we learned how to implement real-time notifications using WebSocket in a Spring Boot application. We covered the setup, configuration, and implementation of the server-side and client-side components. WebSocket provides a powerful mechanism for real-time communication, enabling applications to deliver timely and relevant notifications to users.

By following this guide, you can create a robust real-time notification system that enhances user experience and engagement in your web applications.

Top comments (0)