WebSocketStompClient不会连接到SockJS端点

我正在玩新的(从4.2版开始)java STOMP客户端支持。 我的出发点是入门指南( 使用WebSocket构建交互式Web应用程序 )。

示例中提供了以下端点:

@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/hello").withSockJS(); } 

我可以使用浏览器客户端成功连接。 尝试使用java stomp客户端使用以下命令连接到此端点时:

 WebSocketClient transport = new StandardWebSocketClient(); WebSocketStompClient stompClient = new WebSocketStompClient(transport); stompClient.setMessageConverter(new StringMessageConverter()); String url = "ws://127.0.0.1:8080/hello"; ListenableFuture future = stompClient.connect(url,myHandler); 

我遇到以下exception:

  08:56:30.629 [SimpleAsyncTaskExecutor-1] DEBUG osmsimp.stomp.DefaultStompSession  - 无法连接会话ID = 4e6737da-8f68-691d-375f-9e46f48bc149
 javax.websocket.DeploymentException:来自服务器的HTTP响应[HTTP / 1.1 200 OK
 ]不允许HTTP升级到WebSocket
    在org.apache.tomcat.websocket.WsWebSocketContainer.parseStatus(WsWebSocketContainer.java:637)〜[tomcat-embed-websocket-8.0.20.jar:8.0.20]
     at org.apache.tomcat.websocket.WsWebSocketContainer.processResponse(WsWebSocketContainer.java:621)〜[tomcat-embed-websocket-8.0.20.jar:8.0.20]
    在org.apache.tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.java:309)〜[tomcat-embed-websocket-8.0.20.jar:8.0.20]
    在org.springframework.web.socket.client.standard.StandardWebSocketClient $ 1.call(StandardWebSocketClient.java:152)〜[spring-websocket-4.2.0.BUILD-SNAPSHOT.jar:4.2.0.BUILD-SNAPSHOT]
    在org.springframework.web.socket.client.standard.StandardWebSocketClient $ 1.call(StandardWebSocketClient.java:149)〜[spring-websocket-4.2.0.BUILD-SNAPSHOT.jar:4.2.0.BUILD-SNAPSHOT]
     at java.util.concurrent.FutureTask.run(Unknown Source)[na:1.8.0]
    在java.lang.Thread.run(未知来源)[na:1.8.0] 

经过进一步调查,我根据StompWebSocketIntegrationTests.java中使用的TomcatWebSocketTestServer.java更改了服务器端点配置,如下所示:

 RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy(); registry.addEndpoint("/hello") .setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy)) .setAllowedOrigins("*"); 

我现在可以连接,但浏览器客户端不能。

 GET http://localhost:8080/hello/info 404 (Not Found) 

如果我将.withSockJs()添加到端点配置:

 RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy(); registry.addEndpoint("/hello") .setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy)) .setAllowedOrigins("*") .withSockJs(); 

浏览器客户端可以再次连接,但java客户端又回到了原始错误。

我是否能够在两个客户端之间共享相同的端点,或者在这种情况下是否需要配置两个单独的端点?

以下配置有效:

 RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy(); registry.addEndpoint("/hello") .withSockJS(); registry.addEndpoint("/hello") .setHandshakeHandler(new DefaultHandshakeHandler(upgradeStrategy)) .setAllowedOrigins("*"); 

不确定这是否是设计的(即两个端点具有相同的路径)?

基于Brian-Clozel反馈的更好的解决方案是在配置WebSocketStompClient时使用java SockJsClient作为传输:

 List transports = new ArrayList<>(1); transports.add(new WebSocketTransport( new StandardWebSocketClient()) ); WebSocketClient transport = new SockJsClient(transports); WebSocketStompClient stompClient = new WebSocketStompClient(transport); 

它允许只使用java和javascript客户端可以连接的一个端点:

 @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/hello").withSockJS(); } 

如参考文档中所述 :启用SockJS时,会为您配置多个传输。 首先,客户端发送"GET /info"请求以了解支持的传输,然后根据其function发送请求:

 "http://host:port/myApp/myEndpoint/{server-id}/{session-id}/{transport}" 

现在您不需要为"/hello"端点复制配置。 您宁愿直接使用websocket端点,或者更好的是,将Java SockJS客户端与websocket传输一起使用。 请参阅参考文档中的完整示例 。