WebSocket STOMP refers to using the STOMP protocol (Simple/Streaming Text Oriented Messaging Protocol) over a WebSocket connection.
Here’s the breakdown:
1. WebSocket
- A communication protocol that provides full-duplex, bidirectional communication between client and server over a single TCP connection.
- Unlike HTTP (request-response), WebSockets let the server push messages to the client in real time.
2. STOMP
- Short for Simple (or Streaming) Text-Oriented Messaging Protocol.
- A simple text-based protocol for working with message brokers (like ActiveMQ, RabbitMQ, etc.).
- Defines a standard way to send and subscribe to messages (frames with commands like
SEND
,SUBSCRIBE
,UNSUBSCRIBE
,ACK
, etc.).
2. Configure WebSocket with STOMP
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("/topic"); // topic for subscriptions
config.setApplicationDestinationPrefixes("/app"); // prefix for messages from client
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS(); // endpoint for WebSocket handshake
}
}
3. Create a Message Model
public class ChatMessage {
private String sender;
private String content;
// Getters and setters
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; }
}
4. Create a Controller to handle messages
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class ChatController {
@MessageMapping("/chat") // /app/chat
@SendTo("/topic/messages")
public ChatMessage send(ChatMessage message) throws Exception {
// Could add timestamp, validation, etc.
return message;
}
}
5. Thymeleaf HTML Client (src/main/resources/templates/chat.html
)
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>WebSocket Chat</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.2/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
</head>
<body>
<h2>Chat</h2>
<div>
<input type="text" id="sender" placeholder="Name">
<input type="text" id="message" placeholder="Message">
<button onclick="sendMessage()">Send</button>
</div>
<ul id="messages"></ul>
<script>
let stompClient = null;
function connect() {
const socket = new SockJS('/ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function(msg){
showMessage(JSON.parse(msg.body));
});
});
}
function sendMessage() {
const sender = document.getElementById('sender').value;
const content = document.getElementById('message').value;
stompClient.send("/app/chat", {}, JSON.stringify({sender: sender, content: content}));
}
function showMessage(message) {
const messages = document.getElementById('messages');
const li = document.createElement('li');
li.appendChild(document.createTextNode(message.sender + ": " + message.content));
messages.appendChild(li);
}
connect();
</script>
</body>
</html>
✅ How it works:
- Client connects via SockJS
/ws
. - Sends messages to
/app/chat
(handled by@MessageMapping
in controller). - Server broadcasts to
/topic/messages
. - All subscribed clients receive the message.