Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Real-Time Communication with Spring Boot and WebSocket

Tech May 16 1

Overview of WebSocket Protocol

In modern web development, the demand for instant data synchronization is increasing. Traditional HTTP protocols, operating on a request-response model, are often inefficient for scenarios requiring continuous updates. WebSocket provides a solution by establishing a persistent, full-duplex communication channel over a single TCP connection. This enables bi-directional data exchange between the client browser and the server without the overhead of repeated handshakes.

Core Characteristics

  • Bi-Directional Flow: Unlike HTTP, both parties can initiate communication simultaneously.
  • Persistent State: Once established, the connection remains active until explicitly terminated.
  • Reduced Latency: Eliminates the latency associated with connection negotiation for every packet.
  • Efficient Header Size: Uses minimal framing overhead compared to HTTP headers.
  • Cross-Origin Support: Compatible with CORS policies allowing interaction across domains.

Connection Lifecycle

  1. Handshake: Initiated via an HTTP GET request with an 'Upgrade' header. Upon acceptance, the server responds with status 101 Switching Protocols.
  2. Data Exchange: Messages are encapsulated into frames (text or binary) transmitted over the open socket.
  3. Termination: Either endpoint may send a close frame to gracefully shut down the session.

Common application domains include chat platforms, collaborative editing suites, live dashboards, multiplayer gaming, and push notification systems.

Spring Boot Implementation Guide

To integrate this protocol in to a Java backend using Spring Boot, specific dependencies are required to support the servlet container integration.

Maven Dependencies

Add the starter module for websockets alongside the standard web starter.

    <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>

Server Configuration

A configuration class is necessary to register the endpoint exporter within the application context. This allows the framework to detect annotated WebSocket classses.

@Configuration
public class WsInfrastructureConfig implements WebMvcConfigurer {
    @Bean
    public ServerEndpointExporter wsExporter() {
        return new ServerEndpointExporter();
    }
}

Endpoint Logic and Session Management

The core logic resides in a component annotated with @ServerEndpoint. We utilize a concurrent hash map to track active client sessions identified by a unique ID.

@Component
@ServerEndpoint(value = "/realtime/{client_id}")
public class NotificationHandler {

    private static final ConcurrentMap<String, Session> activeClients = new ConcurrentHashMap<>();
    private static final Logger log = LoggerFactory.getLogger(NotificationHandler.class);
    
    private String currentClientId;

    @OnOpen
    public void handleOpen(Session session, @PathParam("client_id") String clientId) {
        currentClientId = clientId;
        activeClients.put(clientId, session);
        log.info("Client {} connected. Total online: {}", clientId, activeClients.size());
    }

    @OnClose
    public void handleClose() {
        activeClients.remove(currentClientId);
        log.info("Client {} disconnected. Remaining: {}", currentClientId, activeClients.size());
    }

    @OnMessage
    public void handleMessage(String payload, Session session) throws IOException {
        log.info("Incoming payload: {}", payload);
        
        // Parse incoming JSON using ObjectMapper
        // Assuming input structure: { "type": "alert", "msg": "data" }
        session.getBasicRemote().sendText("Echo: " + payload);
    }

    @OnError
    public void handleError(Throwable error) {
        log.error("Critical exception occurred: {}", error.getMessage());
    }
}

Operational Verification

When a client initiates a connection to the defined path, the application logs indicate successful registration. Subsequent message transmission triggers the handler logic, confirming bidirectional capabilities.

[INFO ] 2023-08-31 22:33:32 - Client admin_01 connected. Total online: 1
[INFO ] 2023-08-31 22:33:34 - Incoming payload: {"type":"alert","msg":"test_data"}
[INFO ] 2023-08-31 22:33:34 - Client admin_01 disconnected. Remaining: 0

This setup establishes a foundational real-time channel ready for production expansion, such as implementing broadcasting logic or authentication middleware.

Tags: spring-boot

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.