对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

STOMP 客户端

Spring 提供了基于 WebSocket 的 STOMP 客户端和基于 TCP 的 STOMP 客户端。spring-doc.cadn.net.cn

首先,您可以创建并配置 WebSocketStompClient,如下例所示:spring-doc.cadn.net.cn

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

在前面的示例中,您可以将 StandardWebSocketClient 替换为 SockJsClient, 因为后者也是 WebSocketClient 的一种实现。SockJsClient 可以 使用 WebSocket 或基于 HTTP 的传输作为后备方案。更多详情,请参阅 SockJsClientspring-doc.cadn.net.cn

接下来,您可以建立连接并为 STOMP 会话提供一个处理器,如下例所示:spring-doc.cadn.net.cn

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

当会话准备好可供使用时,处理器会收到通知,如下例所示:spring-doc.cadn.net.cn

public class MyStompSessionHandler extends StompSessionHandlerAdapter {

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

一旦会话建立,即可发送任意有效载荷,并使用配置的MessageConverter进行序列化,如下例所示:spring-doc.cadn.net.cn

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

你也可以订阅目标地址。subscribe 方法需要一个用于处理订阅消息的处理器,并返回一个 Subscription 句柄,你可以使用该句柄来取消订阅。对于每条接收到的消息,处理器可以指定应将消息负载反序列化成的目标 Object 类型,如下例所示:spring-doc.cadn.net.cn

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

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

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

});

要启用 STOMP 心跳,你可以使用 WebSocketStompClient 配置 TaskScheduler, 并可选择自定义心跳间隔(写空闲时间为 10 秒,此时会发送一个心跳;读空闲时间也为 10 秒,此时会关闭连接)。spring-doc.cadn.net.cn

WebSocketStompClient 仅在空闲时(即未发送其他消息时)才会发送心跳。当使用外部代理(broker)时,这可能会带来挑战,因为发往非代理目的地的消息虽然代表了活动,但实际上并不会被转发到代理。在这种情况下,您可以在初始化外部代理时配置一个 handle-broker-relay.html,以确保即使只发送了发往非代理目的地的消息,心跳也会被转发到代理。spring-doc.cadn.net.cn

当你使用 WebSocketStompClient 进行性能测试,从同一台机器模拟成千上万个客户端时,请考虑关闭心跳机制,因为每个连接都会调度自己的心跳任务,而这种方式并未针对在同一台机器上运行大量客户端的场景进行优化。

STOMP 协议还支持回执(receipts)机制,客户端必须添加一个 receipt 头部,服务器在处理完 send 或 subscribe 操作后会返回一个 RECEIPT 帧作为响应。为支持此功能,StompSession 提供了 setAutoReceipt(boolean) 方法,该方法会在后续的每次 send 或 subscribe 操作中自动添加 receipt 头部。 此外,你也可以手动向 StompHeaders 添加回执头部。send 和 subscribe 方法均返回一个 Receiptable 实例,你可以利用它注册回执成功和失败的回调函数。 要使用此功能,你必须为客户端配置一个 TaskScheduler,并指定回执过期前的等待时间(默认为 15 秒)。spring-doc.cadn.net.cn

请注意,StompSessionHandler 本身就是一个 StompFrameHandler,这使得它除了可以通过 handleException 回调处理消息处理过程中产生的异常,以及通过 handleTransportError 处理传输层错误(包括 ConnectionLostException)之外,还能处理 ERROR 帧。spring-doc.cadn.net.cn