# SockJsClient
Spring 提供了一个 SockJS Java 客户端,无需使用浏览器即可连接到远程 SockJS 端点。当需要在公共网络上的两个服务器之间进行双向通信时,这可能特别有用(也就是说,在网络代理可能排除使用 WebSocket 协议的地方)。SockJS Java 客户端对于测试目的也非常有用(例如,模拟大量的并发用户)。
SockJS Java 客户端支持 websocket、xhr-streaming 和 xhr-polling 传输。其余的只有在浏览器中使用才有意义。
你可以用 WebSocketTransport 来配置:
- JSR-356 运行时中的 StandardWebSocketClient。
- JettyWebSocketClient,通过使用 Jetty 9+ 本地 WebSocket API。
- Spring 的 WebSocketClient 的任何实现。
根据定义,XhrTransport 同时支持 xhr-streaming 和 xhr-polling,因为从客户的角度来看,除了用于连接到服务器的 URL 外,没有任何区别。目前,有两种实现方式:
- RestTemplateXhrTransport 使用 Spring 的 RestTemplate 进行 HTTP 请求。
- JettyXhrTransport 使用 Jetty 的 HttpClient 进行 HTTP 请求。
下面的例子展示了如何创建一个 SockJS 客户端并连接到一个 SockJS 端点:
List<Transport> transports = new ArrayList<>(2);
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
transports.add(new RestTemplateXhrTransport());
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.doHandshake(new MyWebSocketHandler(), "ws://example.com:8080/sockjs");
1
2
3
4
5
6
2
3
4
5
6
SockJS 使用 JSON 格式的数组来传递信息。默认情况下,Jackson 2 被使用,并且需要在 classpath 中出现。另外,你可以配置一个SockJsMessageCodec 的自定义实现,并在 SockJsClient 上配置它。
为了使用 SockJsClient 来模拟大量的并发用户,你需要配置底层的 HTTP 客户端(用于 XHR 传输)以允许足够数量的连接和线程。下面的例子展示了如何用 Jetty 做到这一点:
HttpClient jettyHttpClient = new HttpClient();
jettyHttpClient.setMaxConnectionsPerDestination(1000);
jettyHttpClient.setExecutor(new QueuedThreadPool(1000));
1
2
3
2
3
下面的例子显示了服务器端 SockJS 相关的属性(详见 javadoc),你也应该考虑定制这些属性:
@Configuration
public class WebSocketConfig extends WebSocketMessageBrokerConfigurationSupport {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/sockjs").withSockJS()
// 将 streamBytesLimit 属性设为 512KB(默认为 128KB-128*1024)。
.setStreamBytesLimit(512 * 1024)
// 设置 httpMessageCacheSize 属性为 1,000(默认为 100)。
.setHttpMessageCacheSize(1000)
// 将 disconnectDelay 属性设置为 30 属性秒(默认为 5 秒 - 5*1000)。
.setDisconnectDelay(30 * 1000);
}
// ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16