Backend Development 27 min read

Why WebSocket? Advantages, Comparison, and STOMP on Spring WebSocket

This article explains the limitations of HTTP for real‑time communication, compares WebSocket with polling, long‑polling, streaming and SSE, outlines WebSocket's benefits and typical use cases, and then details how STOMP complements WebSocket within Spring's messaging framework, including configuration and message flow.

Yang Money Pot Technology Team
Yang Money Pot Technology Team
Yang Money Pot Technology Team
Why WebSocket? Advantages, Comparison, and STOMP on Spring WebSocket

1 Why WebSocket?

WebSocket is a full‑duplex protocol over TCP that overcomes HTTP’s limitation of client‑initiated communication, enabling scenarios like online chat where either side can push data instantly.

1.1 Technical alternatives for push scenarios

Before WebSocket, solutions such as Polling, Long‑Polling, iframe/Flash streaming, and Server‑Sent Events (SSE) were used, each with drawbacks in latency, resource consumption, or bidirectional capability.

1.2 Advantages of WebSocket

Bidirectional communication

Low latency

Binary support without format restrictions

Small framing overhead

Extensible via sub‑protocols

1.3 Typical use cases

Real‑time chat, social notifications, multiplayer games, collaborative editing, financial market feeds, location‑based services, etc.

1.4 Comparison with other streaming protocols

WebSocket provides true duplex communication, whereas protocols like HLS, RTMP are oriented to media streaming with different reliability requirements.

2 Why STOMP on WebSocket?

2.1 What is missing from raw WebSocket?

WebSocket defines only the transport; it does not prescribe a message format, routing, or subscription semantics. STOMP supplies a simple text‑based messaging protocol that adds commands, headers, and bodies.

2.2 STOMP basics

STOMP frames consist of a COMMAND, a set of HEADERS, and an optional BODY. Example:

/**
 * Handle an inbound message from a WebSocket client.
 */
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage
message) throws Exception {
    // Session management omitted for brevity
    SubProtocolHandler protocolHandler = findProtocolHandler(session);
    protocolHandler.handleMessageFromClient(session, message, this.clientInboundChannel);
    // Heart‑beat and cleanup omitted
}

/**
 * Handle an outbound Spring Message to a WebSocket client.
 */
@Override
public void handleMessage(Message
message) throws MessagingException {
    String sessionId = resolveSessionId(message);
    if (sessionId == null) {
        logger.error("Couldn't find session id in " + message);
        return;
    }
    WebSocketSessionHolder holder = this.sessions.get(sessionId);
    if (holder == null) {
        logger.debug("No session for " + message);
        return;
    }
    WebSocketSession session = holder.getSession();
    try {
        findProtocolHandler(session).handleMessageToClient(session, message);
    } catch (Exception ex) {
        // error handling omitted
    }
}

Client commands include CONNECT, SEND, SUBSCRIBE, BEGIN, COMMIT, ABORT, DISCONNECT; server commands include CONNECTED, MESSAGE, RECEIPT, ERROR.

2.3 Spring’s STOMP‑WebSocket solution

Spring 4+ provides spring-websocket and spring-messaging modules. Using @EnableWebSocketMessageBroker and a configuration class you can set up a simple broker, application prefixes, user destinations, and optionally relay messages to RabbitMQ.

3 Understanding the message flow

Pipes‑and‑Filters model

Spring‑messaging implements the Pipes‑and‑Filters pattern with three core interfaces: Message , MessageHandler , and MessageChannel . Handlers act as filters, channels as pipes.

Key components

SubProtocolWebSocketHandler converts between raw WebSocketMessage and protocol‑specific Message objects.

ClientInboundChannel routes incoming messages to handlers such as WebSocketAnnotationMethodMessageHandler , SimpleBrokerMessageHandler , and UserDestinationMessageHandler .

ClientOutboundChannel sends processed messages back through SubProtocolWebSocketHandler .

Three communication modes

Topic‑based broadcast ( /topic/** )

App‑destined request‑response style ( /app/** ) mapped to @MessageMapping methods

User‑specific destinations ( /user/** ) for private messages

Configuration example

@Configuration
@EnableWebSocketMessageBroker
public class StompWebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Autowired
    private YqgHandshakeInterceptor yqgHandshakeInterceptor;

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
        config.enableStompBrokerRelay("/exchange","/topic","/queue","/amq/queue")
              .setVirtualHost("rabbit_mq_host")
              .setRelayHost("localhost")
              .setClientLogin("root")
              .setClientPasscode("root")
              .setSystemLogin("root")
              .setSystemPasscode("root")
              .setSystemHeartbeatSendInterval(5000)
              .setSystemHeartbeatReceiveInterval(4000);
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/establish-websocket-sockjs").withSockJS();
        registry.addEndpoint("/establish-websocket")
                .setAllowedOrigins("*")
                .setHandshakeHandler(handshakeHandler())
                .addInterceptors(yqgHandshakeInterceptor);
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(webSocketInterceptor);
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(1000);
        executor.setThreadNamePrefix("yqg");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        registration.taskExecutor(executor);
    }
}

4 Conclusion

WebSocket provides efficient, low‑overhead, bidirectional communication for real‑time applications. Adding STOMP via Spring’s WebSocket support supplies a robust messaging model, seamless integration with other Spring projects, and optional broker relay to systems like RabbitMQ, making it a practical choice for modern backend development.

Real-timeSpringWebSocketMessageBrokerSTOMP
Yang Money Pot Technology Team
Written by

Yang Money Pot Technology Team

Enhancing service efficiency with technology.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.