java - WebSocketStompClient 不会连接到 SockJS 端点

标签 java spring spring-websocket

我正在使用新的(从 4.2 版开始)java STOMP 客户端支持。我的出发点是入门指南 (Using WebSocket to build an interactive web application)。

示例中提供了以下端点:

@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<StompSession> future = stompClient.connect(url,myHandler);

我遇到以下异常:

08:56:30.629 [SimpleAsyncTaskExecutor-1] DEBUG o.s.m.simp.stomp.DefaultStompSession - Failed to connect session id=4e6737da-8f68-691d-375f-9e46f48bc149
javax.websocket.DeploymentException: The HTTP response from the server [HTTP/1.1 200 OK
] did not permit the HTTP upgrade to WebSocket
    at 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]
    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]
    at 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]
    at java.lang.Thread.run(Unknown Source) [na:1.8.0] 

Upon further investigation I changed the server endpoint configuration based on TomcatWebSocketTestServer.java used in StompWebSocketIntegrationTests.java as follows:

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<Transport> 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();
}

关于java - WebSocketStompClient 不会连接到 SockJS 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30413380/

相关文章:

java - 为什么包含 blob 的 INSERT INTO 不保留记录

java - 序列化Java标准类时LocalClass不兼容

java - 当自定义 Servlet Filter 中抛出错误时, doFilter 方法会被多次调用

spring - 阻止 http 请求进入在 Amazon ELB 后面运行的 Spring boot restful 服务

java - 使用 Spring MVC RequestMappingHandlerMapping 和 Spring Websocket 的 ServletWebSocketHandlerRegistry 处理相同的 URL

java - 异步同步

java - 使用 StepExecutionContext/JobExecutionContext 共享大值 Hashmap 的后果

java - 是否可以在同一上下文中服务器 websocket 处理程序和普通 servlet?

amazon-web-services - 为什么 grails websockets 连接失败,但在使用 AWS ELB 时继续接收浏览器中已订阅的消息?

java - 在 Java 中对泛型进行排序