Spring提供了一个基于WebSocket的STOMP客户端和一个基于TCP的STOMP客户端。
首先,你可以创建并配置WebSocketStompClient
,如下所示:
WebSocketClient webSocketClient = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient);
stompClient.setMessageConverter(new StringMessageConverter());
stompClient.setTaskScheduler(taskScheduler); *// for heartbeats*
在上述示例中,你可以将StandardWebSocketClient
替换为SockJsClient
,因为SockJsClient
也是WebSocketClient
的实现。SockJsClient
可以使用WebSocket或HTTP作为后备传输。有关更多详细信息,请参见[SockJsClient](<https://docs.spring.io/spring-framework/reference/web/websocket/fallback.html#websocket-fallback-sockjs-client>)
。
接下来,你可以建立连接并为STOMP会话提供一个处理器,如下例所示:
String url = "ws://127.0.0.1:8080/endpoint";
StompSessionHandler sessionHandler = new MyStompSessionHandler();
stompClient.connect(url, sessionHandler);
当会话准备好使用时,处理器会被通知,如下所示:
public class MyStompSessionHandler extends StompSessionHandlerAdapter {@Overridepublic void afterConnected(StompSession session, StompHeaders connectedHeaders) {*// ...*}
}
一旦会话建立,任何payload都可以通过配置的MessageConverter
序列化后发出,如下所示:
session.send("/topic/something", "payload");
你还可以订阅destinations。subscribe
方法需要一个用于订阅上的消息处理器,并返回一个Subscription
句柄,你可以使用它来取消订阅。对于每个接收到的消息,处理器可以指定目标的Object
类型,以将payload 反序列化为该类型,如下所示:
session.subscribe("/topic/something", new StompFrameHandler() {@Overridepublic Type getPayloadType(StompHeaders headers) {return String.class;}@Overridepublic void handleFrame(StompHeaders headers, Object payload) {*// ...*}});
要启用STOMP心跳检测,你可以在WebSocketStompClient
配置TaskScheduler
,并可以自定义心跳间隔(默认情况下,写入不活动为 10 秒,这会导致发送心跳;读取不活动为 10 秒,这会关闭连接)。
WebSocketStompClient
仅在不活跃时发送心跳,即当没有发送其他消息时。这在使用外部代理时可能会带来挑战,因为带有非代理destination 的消息代表活动,但实际并未转发到代理。在这种情况下,你可以在初始化外部代理时配置一个TaskScheduler
,确保即使只发送带有非代理destination 的消息,心跳也会被转发到代理。
当你使用
WebSocketStompClient
进行性能测试以模拟同一台计算机上的数千个客户端时,请考虑关闭心跳,因为每个连接都会安排自己的心跳任务,并且对于在同一台计算机上运行的大量客户端而言,这并未进行优化。
STOMP协议还支持收据,客户端必须添加一个receipt
标头,服务器在处理完发送或订阅后,会响应RECEIPT帧。为此,StompSession
提供了setAutoReceipt(boolean)
配置,它会在每个后续的发送或订阅事件上添加一个receipt
头部。或者,你也可以手动向StompHeaders
添加一个receipt
标头。发送和订阅方法都返回一个Receiptable
实例,你可以使用它来注册收据成功和失败的回调。为此功能,你必须这客户端配置TaskScheduler
,以及收据过期前的时间(默认为15秒)。
请注意,StompSessionHandler
本身是一个 StompFrameHandler
,除了用于消息处理异常的handleException
回调和用于传输级错误(包括 ConnectionLostException
)的handleTransportError
之外,它还可以处理 ERROR 帧。