2015-05-23 15 views
7

Tôi đang chơi đùa với các mới (như các phiên bản 4.2) java STOMP hỗ trợ khách hàng. Điểm xuất phát của tôi là hướng dẫn bắt đầu (Using WebSocket to build an interactive web application).WebSocketStompClient sẽ không kết nối với thiết bị đầu cuối SockJS

Tiêu chí sau đây được cung cấp trong ví dụ:

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

tôi thành công có thể kết nối bằng cách sử dụng client trình duyệt. Khi cố gắng để kết nối với thiết bị đầu cuối này bằng cách sử dụng client java stomp sử dụng như sau:

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); 

tôi gặp phải trường hợp ngoại lệ sau đây:

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]

Sau khi điều tra thêm tôi đã thay đổi cấu hình máy chủ đầu cuối dựa trên TomcatWebSocketTestServer.java được sử dụng trong StompWebSocketIntegrationTests.java như sau:

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

Bây giờ tôi có thể kết nối, nhưng khách hàng trình duyệt không thể.

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

Nếu tôi thêm .withSockJs() để cấu hình thiết bị đầu cuối:

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

trình duyệt trên client có thể kết nối một lần nữa, nhưng khách hàng java là trở lại các lỗi ban đầu.

Tôi có thể chia sẻ cùng một điểm cuối giữa cả hai khách hàng hoặc tôi có cần phải định cấu hình hai điểm cuối riêng biệt trong trường hợp này không?

Trả lời

15

Các công trình cấu hình sau:

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

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

Không chắc nếu điều này là do thiết kế (ví dụ: hai điểm đầu cuối với cùng một con đường)?

Một giải pháp tốt hơn dựa trên phản hồi của Brian-Clozel là sử dụng các SockJsClient java như một phương tiện giao thông khi cấu hình WebSocketStompClient:

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

cho phép người sử dụng chỉ có một thiết bị đầu cuối mà java và javascript clients có thể cả hai kết nối:

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

Như đã nêu trong the reference documentation: khi bật SockJS, nhiều phương tiện được định cấu hình cho bạn. Thứ nhất, khách hàng gửi một yêu cầu "GET /info" biết về vận tải hỗ trợ và sau đó gửi một yêu cầu tùy thuộc vào khả năng của mình:

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

Bây giờ bạn không cần phải lặp lại cấu hình cho bạn "/hello" endpoint. Bạn muốn trực tiếp sử dụng điểm cuối websocket, hoặc tốt hơn, hãy sử dụng máy khách Java SockJS với một vận chuyển websocket. Xem the complete example in the reference documentation.

+0

Cảm ơn, câu trả lời của bạn là hữu ích. Tôi đã cập nhật câu trả lời của mình với cấu hình mới dựa trên phản hồi của bạn. Xin lỗi tôi chưa thể upvote (không đủ điểm danh tiếng). – stacktrace

Các vấn đề liên quan