Chapter 8.4☕ 16 min read

WebSockets Real-Time

HTTP asks and answers. WebSockets let both sides talk any time.

01The Concept: Full-Duplex Communication

The Hyderabad Metro Transit Control Room Analogy:

In an HTTP REST API, a passenger presses a button at the station to ask if the train is coming. The control room answers, and the call drops. The passenger must keep pressing the button (Polling).

With WebSockets, the passenger and the control room establish a walkie-talkie connection. Either side can talk at any time, instantly, without hanging up. This is called full-duplex, real-time communication.

02Technical Explanation
  1. STOMP (Simple Text Oriented Messaging Protocol): A protocol layered on top of WebSockets. It allows us to route messages to specific topics (like chat rooms).
  2. @MessageMapping: The WebSocket equivalent of @GetMapping. It listens for incoming messages from the client.
  3. @SendTo: Broadcasts the method’s return value to all users subscribed to a specific topic.
03Full Working Code: Live Chat Endpoint

Add the WebSocket dependency.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

1. WebSocket Configuration (WebSocketConfig.java)

package com.devinhyderabad;

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) {
// 1. Messages sent to "/topic" will be broadcast to all subscribers
config.enableSimpleBroker("/topic");
// 2. Messages sent by clients should be prefixed with "/app"
config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 3. The frontend connects to this endpoint (like a REST API URL)
registry.addEndpoint("/ws-chat").withSockJS();
}
}

2. The Chat Controller (ChatController.java)

package com.devinhyderabad;

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

@Controller
public class ChatController {

// 1. When a message arrives at "/app/sendMessage"
@MessageMapping("/sendMessage")
// 2. The return value is broadcast to everyone listening on "/topic/messages"
@SendTo("/topic/messages")
public ChatMessage broadcastMessage(ChatMessage message) {
return message;
}
}

class ChatMessage {
private String sender;
private String content;

public String getSender() { return sender; }
public void setSender(String sender) { this.sender = sender; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
}
04Code Walkthrough

The setup has three key parts:

  • WebSocketConfig: Configures a simple in-memory message broker (/topic) for broadcasting, and sets the client prefix to /app. It also registers the STOMP endpoint at /ws-chat with SockJS fallback for browsers that don’t support WebSockets.
  • @MessageMapping: When a JavaScript client sends stompClient.send("/app/sendMessage", {}, message), this method receives it.
  • @SendTo: The return value is automatically sent to all clients subscribed to the /topic/messages channel.
05Why It Matters / Interview Note

Interview Question: “What is the difference between HTTP Polling, Long Polling, and WebSockets?”

Answer:

  1. Polling: The client asks the server every 5 seconds “Any updates?”. (Wastes bandwidth).
  2. Long Polling: The client asks, and the server holds the connection open until an update arrives. (Hard to scale).
  3. WebSockets: A single persistent TCP connection where the server can push data instantly at any time. (Most efficient for real-time).

Enterprise Note: If you have multiple Spring Boot instances behind a load balancer, simple STOMP broker won’t work. A message sent to Instance A won’t reach users connected to Instance B. Enterprise apps use an external message broker like RabbitMQ or Redis Pub/Sub to sync WebSocket messages across all instances.

Key Takeaways

  • ✅ WebSockets enable full-duplex communication (both sides can talk at any time)
  • ✅ STOMP is a messaging protocol layered on top of WebSockets for routing
  • ✅ @MessageMapping listens for client messages; @SendTo broadcasts responses
  • ✅ SockJS provides fallback for browsers without native WebSocket support
  • ✅ For multi-instance deployments, use external broker like RabbitMQ or Redis