Introduction

WebSockets have become an essential technology for building real-time applications, enabling seamless communication between clients and servers. In this blog post, we will explore how to implement WebSockets with Spring 6, the latest version of the popular Java framework. We will create a simple chat application to demonstrate this process step-by-step.

Getting Started

To create a new Spring 6 project, visit the Spring Initializr (https://start.spring.io/) and select the following dependencies:

  • Web
  • WebSocket

Generate the project and open it in your favorite IDE.

Project Structure

Here is an overview of the project structure:

  • src/main/java
    • com.example.websocketdemo
      • WebSocketDemoApplication.java
      • config
        • WebSocketConfig.java
      • controller
        • ChatController.java
      • model
        • Message.java

WebSocket Configuration

First, let’s configure the WebSocket. Create a new package config and a new class WebSocketConfig.java:

package com.example.websocketdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(chatController(), "/chat");
    }

    @Bean
    public ChatController chatController() {
        return new ChatController();
    }
}

This class enables and configures WebSocket support for our application.

Message Model

Now, let’s create the Message model class in the model package:

package com.example.websocketdemo.model;

public class Message {
    private String sender;
    private String content;

    // Constructors, Getters, and Setters
}

ChatController

Next, create the ChatController class in the controller package:

package com.example.websocketdemo.controller;

import com.example.websocketdemo.model.Message;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.concurrent.CopyOnWriteArrayList;

@RestController
public class ChatController extends TextWebSocketHandler {
    private final CopyOnWriteArrayList<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        for (WebSocketSession s : sessions) {
            s.sendMessage(new TextMessage(message.getPayload()));
        }
    }
}

In this class, we extend TextWebSocketHandler and override the afterConnectionEstablished and handleTextMessage methods to handle WebSocket connections and messages.

Testing the Application

To test the application, you can use any WebSocket client or build a simple HTML page with JavaScript.

Here’s a basic HTML file to test the chat functionality:

<!DOCTYPE html>
<html>
<head>
    <title>Spring 6 WebSocket Chat</title>
    <script>
        var socket = new WebSocket('ws://localhost:8080/chat');

        socket.onmessage = function (event) {
            var messages = document.getElementById('messages');
            messages.innerHTML += '<p>' + event.data + '</p>';
        };

        function sendMessage() {
            var input = document.getElementById('input');
            socket.send(input.value);
            input.value = '';
        }
    </script>
</head>
<body>
<h1>Spring 6 WebSocket Chat</h1>
    <div id="messages"></div>
    <input type="text" id="input" placeholder="Type your message">
    <button onclick="sendMessage()">Send</button>
</body>
</html>

Save this file as index.html and open it in your browser. Open multiple instances of the file to simulate a chat between multiple users. Type a message in one instance and press “Send.” The message should appear in all instances.

Conclusion

In this blog post, we demonstrated how to implement WebSockets in a Spring 6 application by creating a simple chat application. This example can be further expanded and customized for more advanced use cases, such as group chats or authentication. With Spring 6 and WebSockets, building real-time applications has never been easier.

Next Steps

To further enhance your chat application, you can consider adding the following features:

  1. User Authentication: Implement a user authentication system using Spring Security to ensure that only authenticated users can access the chat.
  2. Group Chats: Allow users to join specific chat rooms and broadcast messages only to members of the same chat room.
  3. Message Persistence: Store chat messages in a database, allowing users to view message history when they join the chat.
  4. Typing Indicators: Show a “User is typing…” message when a user is typing a message.
  5. Read Receipts: Display read receipts to show when a message has been seen by other users.
  6. Emojis and Rich Media: Allow users to send emojis, images, and other rich media in their messages.
  7. Frontend Framework Integration: Integrate the chat application with popular frontend frameworks like React, Angular, or Vue.js to create a more robust and responsive user interface.
  8. Scalability: Implement a scalable architecture using tools like RabbitMQ or Apache Kafka to handle large numbers of users and high message throughput.

By implementing these features, you can create a full-fledged chat application that meets the needs of various use cases. Moreover, the combination of Spring 6 and WebSockets provides an excellent foundation for building other real-time applications, such as notifications, live data updates, and collaboration tools. With these powerful tools at your disposal, the possibilities are endless.

Categories: Hands-On