This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.1!

STOMP Client

Spring provides a STOMP over WebSocket client and a STOMP over TCP client.

To begin, you can create and configure WebSocketStompClient, as the following example shows:

WebSocketClient webSocketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
stompClient.setMessageConverter(new StringMessageConverter());
stompClient.setTaskScheduler(taskScheduler); // for heartbeats

In the preceding example, you could replace StandardWebSocketClient with SockJsClient, since that is also an implementation of WebSocketClient. The SockJsClient can use WebSocket or HTTP-based transport as a fallback. For more details, see SockJsClient.

Next, you can establish a connection and provide a handler for the STOMP session, as the following example shows:

String url = "ws://127.0.0.1:8080/endpoint";
StompSessionHandler sessionHandler = new MyStompSessionHandler();
stompClient.connect(url, sessionHandler);

When the session is ready for use, the handler is notified, as the following example shows:

public class MyStompSessionHandler extends StompSessionHandlerAdapter {

	@Override
	public void afterConnected(StompSession session, StompHeaders connectedHeaders) {
		// ...
	}
}

Once the session is established, any payload can be sent and is serialized with the configured MessageConverter, as the following example shows:

session.send("/topic/something", "payload");

You can also subscribe to destinations. The subscribe methods require a handler for messages on the subscription and returns a Subscription handle that you can use to unsubscribe. For each received message, the handler can specify the target Object type to which the payload should be deserialized, as the following example shows:

session.subscribe("/topic/something", new StompFrameHandler() {

	@Override
	public Type getPayloadType(StompHeaders headers) {
		return String.class;
	}

	@Override
	public void handleFrame(StompHeaders headers, Object payload) {
		// ...
	}

});

To enable STOMP heartbeat, you can configure WebSocketStompClient with a TaskScheduler and optionally customize the heartbeat intervals (10 seconds for write inactivity, which causes a heartbeat to be sent, and 10 seconds for read inactivity, which closes the connection).

WebSocketStompClient sends a heartbeat only in case of inactivity, i.e. when no other messages are sent. This can present a challenge when using an external broker since messages with a non-broker destination represent activity but aren’t actually forwarded to the broker. In that case you can configure a TaskScheduler when initializing the External Broker which ensures a heartbeat is forwarded to the broker also when only messages with a non-broker destination are sent.

When you use WebSocketStompClient for performance tests to simulate thousands of clients from the same machine, consider turning off heartbeats, since each connection schedules its own heartbeat tasks and that is not optimized for a large number of clients running on the same machine.

The STOMP protocol also supports receipts, where the client must add a receipt header to which the server responds with a RECEIPT frame after the send or subscribe are processed. To support this, the StompSession offers setAutoReceipt(boolean) that causes a receipt header to be added on every subsequent send or subscribe event. Alternatively, you can also manually add a receipt header to the StompHeaders. Both send and subscribe return an instance of Receiptable that you can use to register for receipt success and failure callbacks. For this feature, you must configure the client with a TaskScheduler and the amount of time before a receipt expires (15 seconds by default).

Note that StompSessionHandler itself is a StompFrameHandler, which lets it handle ERROR frames in addition to the handleException callback for exceptions from the handling of messages and handleTransportError for transport-level errors including ConnectionLostException.

You can use the inboundMessageSizeLimit and outboundMessageSizeLimit properties of WebSocketStompClient to limit the maximum size of inbound and outbound WebSocket messages. When an outbound STOMP message exceeds the limit, it is split into partial frames, which the receiver would have to reassemble. By default, there is no size limit for outbound messages. When an inbound STOMP message size exceeds the configured limit, a StompConversionException is thrown. The default size limit for inbound messages is 64KB.

WebSocketClient webSocketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
stompClient.setInboundMessageSizeLimit(64 * 1024); // 64KB
stompClient.setOutboundMessageSizeLimit(64 * 1024); // 64KB