Kir*_* S. 19 tomcat stomp websocket spring-websocket java-websocket
我收到了一个Web应用程序,使用Spring通过WebSockets Messaging使用STOMP实现,类似于此处描述的(在后端使用RabbitMQ).它在Tomcat上运行,我可以使用常规URL连接到应用程序(例如http://host/server/).我还获得了一个演示客户端 - 一个JSPX页面,它使用了Modernizr WebSockets和SockJS.demo客户端中的连接代码如下所示:
if (Modernizr.websockets) {
socket = new WebSocket('ws://host/server/endpointx');
}
else {
socket = new SockJS('/server/endpointy');
}
stompClient = Stomp.over(socket);
stompClient.connect(headers, function(frame) { ... });
....
Run Code Online (Sandbox Code Playgroud)
演示客户端工作正常(当我在浏览器中加载JSPX页面时,我可以连接到服务器).但我的目标是使用一些Java STOMP库连接到同一台服务器.问题是,我尝试过的库需要主机和端口作为连接参数:例如,使用ActiveMQ Stomp库:
StompConnection connection = new StompConnection();
connection.open("host", port);
connection.connect(new HashMap<String, String>());
Run Code Online (Sandbox Code Playgroud)
如果我指定port为61613,连接成功,但我直接打了RabbitMQ,而不是我的服务器(这不是我想要的).如果我指定8080(或80),在连接时我得到一个错误
位于org.apache.activemq.transport.stomp.StompConnection的org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:137)java.io.DataInputStream.readByte(未知来源)的java.io.EOFException .receive(StompConnection.java:77)org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:68)atg.apache.activemq.transport.stomp.StompConnection.connect(StompConnection.java:139) )at .... stomp.impl.activemq.ActiveMQStompDriver.connect(ActiveMQStompDriver.java:39)... 25更多
和跟踪显示这是因为CONNECT帧永远不会收到预期的CONNECTED帧(事实上,它不会收到任何回复).
所以我很困惑:我使用了错误的端口吗?或处理一些库不兼容?或者我是否需要以某种方式指示Tomcat我想要将HTTP连接升级到WebSockets?
如果上面的问题很难回答,那么这个问题同样有用:如何通过使用Java在Tomcat上运行的WebSockets消息通道上的STOMP连接到Spring应用程序?
当我找到答案时我应该发布答案。为了实现 Java 客户端,连接到 Tomcat,而不是直接连接到 RabbitMQ,Java 客户端不仅应该实现 STOMP Over WebSockets,还应该实现开放握手:
打开握手旨在与基于 HTTP 的服务器端软件和中介兼容,以便与该服务器通信的 HTTP 客户端和与该服务器通信的 WebSocket 客户端都可以使用单个端口。为此,WebSocket客户端的握手是一个HTTP升级请求
我尝试使用的库只是缺少此功能。他们尝试直接进行WebSocket连接而不需要握手。
所以回答我自己的问题:
我最终使用了Spring WebSocket 库,它可以轻松实现这一切。这是最简单的设置:
taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(N); // N = number of threads
taskScheduler.afterPropertiesSet();
stompClient = new WebSocketStompClient(new StandardWebSocketClient());
stompClient.setTaskScheduler(taskScheduler);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
WebSocketHttpHeaders handshakeHeaders = new WebSocketHttpHeaders(); // you can add additional headers here for Tomcat
// Here's the main piece other libraries were missing:
// The following request will perform both, handshake and connection
// hence it gets both sets of headers (for Tomcat and for Stomp)
ListenableFuture<StompSession> future = stompClient.connect(
url,
handshakeHeaders,
new StompHeaders(),
new CustomStompSessionHandlerAdapter(this)); // called from class that also was implementing CustomStompSessionHandlerAdapter, but this could be separate class as well.
Run Code Online (Sandbox Code Playgroud)
另请参阅Spring 参考中的 WebSocket 支持部分
| 归档时间: |
|
| 查看次数: |
914 次 |
| 最近记录: |