web-dev-qa-db-ja.com

WebSocketStompClientはSockJSエンドポイントに接続しません

私は新しい(バージョン4.2以降)で遊んでいますJava STOMPクライアントサポート。私の出発点は入門ガイドです( WebSocketを使用してインタラクティブなWebアプリケーションを構築する )。

この例では、次のエンドポイントが提供されています。

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

ブラウザクライアントを使用して正常に接続できます。 Java stomp client using the以下を使用して、このエンドポイントに接続しようとした場合:

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

次の例外が発生します。

08:56:30.629 [SimpleAsyncTaskExecutor-1] DEBUGosmsimp.stomp.DefaultStompSession-セッションid = 4e6737da-8f68-691d-375f-9e46f48bc149 
 javax.websocket.DeploymentExceptionの接続に失敗しました:サーバーからのHTTP応答[HTTP/1.1 200 OK 
は、org.Apache.Tomcat.websocket.WsWebSocketContainer.parseStatus(WsWebSocketContainer.Java:637)〜[Tomcat-embed-でWebSocket 
へのHTTPアップグレードを許可しませんでした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] 
 at org.Apache.Tomcat.websocket.WsWebSocketContainer.connectToServer(WsWebSocketContainer.Java:309)〜[Tomcat-embed-websocket-8.0.20.jar:8.0.20] 
 at 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.clie nt.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] 
 at Java.lang.Thread.run(Unknown Source)[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クライアントは元のエラーに戻ります。

両方のクライアント間で同じエンドポイントを共有できる必要がありますか、それともこの場合、2つの別々のエンドポイントを構成する必要がありますか?

12
stacktrace

次の構成が機能します。

RequestUpgradeStrategy upgradeStrategy = new TomcatRequestUpgradeStrategy();
registry.addEndpoint("/hello")
        .withSockJS();

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

これが設計によるものかどうかわからない(つまり、同じパスを持つ2つのエンドポイント)?

Brian-Clozelのフィードバックに基づくより良い解決策は、WebSocketStompClientを構成するときにトランスポートとしてJava SockJsClientを使用することです。

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

これにより、Javaとjavascriptクライアントの両方が接続できるエンドポイントを1つだけ使用できます。

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

リファレンスドキュメント :で述べられているように、SockJSを有効にすると、複数のトランスポートが構成されます。最初に、クライアントはサポートされているトランスポートについて知るために"GET /info"要求を送信し、次にその機能に応じて要求を送信します。

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

これで、"/hello"エンドポイントの構成を複製する必要はありません。 WebSocketエンドポイントを直接使用するか、Java SockJSクライアントとWebSocketトランスポートを使用することをお勧めします。 リファレンスドキュメントの完全な例 を参照してください。

6
Brian Clozel

Httpフィルター(shiroフィルターなど)またはHandlerInterceptorを確認できます。

0
qyvlik