gpt4 book ai didi

tomcat - 通过从 Java 客户端使用 Spring 4 实现的 WebSockets 连接到 Stomp

转载 作者:行者123 更新时间:2023-11-28 21:44:24 27 4
gpt4 key购买 nike

我收到了一个 Web 应用程序,它是使用 STOMP over WebSockets Messaging 使用 Spring 实现的,类似于描述的内容 here (在后端使用 RabbitMQ)。它在 Tomcat 上运行,我可以使用常规 URL(例如 http://host/server/)连接到应用程序。我还获得了一个演示客户端——一个使用 Modernizr WebSockets 和 SockJS 的 JSPX 页面。演示客户端中的连接代码如下所示:

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) { ... });
....

演示客户端工作正常(当我在浏览器中加载 JSPX 页面时,我可以连接到服务器)。但我的目标是使用一些 Java STOMP 库连接到同一台服务器。问题是,我试过的库需要 hostport 作为连接参数:例如 ActiveMQ Stomp library :

StompConnection connection = new StompConnection();
connection.open("host", port);
connection.connect(new HashMap<String, String>());

如果我将 port 指定为 61613,连接会成功,但我直接访问了 RabbitMQ,而不是我的服务器(这不是我想要的)。如果我指定 8080(或 80),在连接时我会收到错误

java.io.EOFException at java.io.DataInputStream.readByte(Unknown Source) at org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:137) at org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:77) at org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:68) at org.apache.activemq.transport.stomp.StompConnection.connect(StompConnection.java:139) at ....stomp.impl.activemq.ActiveMQStompDriver.connect(ActiveMQStompDriver.java:39) ... 25 more

并且跟踪显示这是因为 CONNECT 帧从未收到预期的 CONNECTED 帧(事实上,它没有收到任何返回信息)。

所以我很疑惑:我是不是用错了端口?或处理一些图书馆不兼容?还是我需要以某种方式指示我想要 upgrade HTTP connection to WebSockets 的 Tomcat ?

如果上述问题难以回答,那么这个问题同样有用:如何使用 Java 通过在 Tomcat 上运行的 WebSockets 消息 channel 通过 STOMP 连接到 Spring 应用程序?

最佳答案

我应该在找到答案时发布答案。为了实现 Java 客户端,连接到 Tomcat,而不是直接连接到 RabbitMQ,Java 客户端不仅应该实现 STOMP Over WebSockets,还应该 an opening handshake :

The opening handshake is intended to be compatible with HTTP-basedserver-side software and intermediaries, so that a single port can beused by both HTTP clients talking to that server and WebSocketclients talking to that server. To this end, the WebSocket client'shandshake is an HTTP Upgrade request

我尝试使用的库只是缺少此功能。他们试图在没有握手的情况下直接执行 WebSocket 连接。

所以回答我自己的问题:

  • 库必须支持打开握手
  • 对于主机和端口,您需要指定 Tomcat 的主机(与 RabbitMQ 不同)和Web 端口(例如 8080),而不是 RabbitMQ 端口

我最终使用了 Spring WebSocket library ,这让这一切变得很容易。这是最简单的设置:

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.

另见 WebSocket Support section in Spring reference

关于tomcat - 通过从 Java 客户端使用 Spring 4 实现的 WebSockets 连接到 Stomp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38819869/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com