对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-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 仅在无活动时发送心跳,即当没有其他消息发送时。当使用外部代理时,这可能会带来挑战,因为具有非代理目标的消息表示有活动,但并不会实际转发到代理。在这种情况下,您可以在初始化 外部代理 时配置 TaskScheduler,这可以确保当仅发送具有非代理目标的消息时,心跳也会转发到代理。spring-doc.cadn.net.cn

当您在性能测试中使用 WebSocketStompClient 来从同一台机器模拟数千个客户端时,建议关闭心跳功能,因为每个连接都会安排自己的心跳任务,这在同一台机器上运行大量客户端时并不是最优的。

STOMP协议还支持确认,其中客户端必须添加一个receipt头,服务器在发送或订阅处理后会通过RECEIPT帧进行响应。为了支持此功能,StompSession提供了setAutoReceipt(boolean),这会导致在每次后续的发送或订阅事件中添加一个receipt头。 或者,您也可以手动将确认头添加到StompHeaders中。 发送和订阅都会返回一个Receiptable的实例,您可以使用它来注册确认成功和失败的回调。 为此功能,您必须将客户端配置为TaskScheduler,以及确认过期前的时间(默认为15秒)。spring-doc.cadn.net.cn

请注意,StompSessionHandler本身是一个StompFrameHandler,这使得它除了可以处理消息处理中的异常的handleException回调外,还可以处理错误帧,以及handleTransportError用于传输层错误,包括ConnectionLostExceptionspring-doc.cadn.net.cn