Tomcat 从Java客户端连接到使用Spring 4实现的Stomp over WebSocket

Tomcat 从Java客户端连接到使用Spring 4实现的Stomp over WebSocket,tomcat,websocket,stomp,spring-websocket,java-websocket,Tomcat,Websocket,Stomp,Spring Websocket,Java Websocket,我收到了一个Web应用程序,它是通过Spring使用STOMP over WebSockets消息传递实现的,与前面描述的类似(后端使用RabbitMQ)。它在Tomcat上运行,我可以使用常规URL(例如http://host/server/)。我还得到了一个演示客户端——一个使用Modernizer WebSocket和SockJS的JSPX页面。演示客户端中的连接代码如下所示: if (Modernizr.websockets) { socket = new WebSocket('

我收到了一个Web应用程序,它是通过Spring使用STOMP over WebSockets消息传递实现的,与前面描述的类似(后端使用RabbitMQ)。它在Tomcat上运行,我可以使用常规URL(例如
http://host/server/
)。我还得到了一个演示客户端——一个使用Modernizer WebSocket和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页面时,我可以连接到服务器)。但我的目标是使用一些JavaStomp库连接到同一台服务器。问题是,我尝试的库需要主机端口作为连接参数:例如:

StompConnection connection=new StompConnection();
连接。打开(“主机”,端口);
connection.connect(新的HashMap());
如果我将
port
指定为
61613
,则连接成功,但我直接命中RabbitMQ,而不是我的服务器(这不是我想要的)。如果我指定了
8080
(或
80
),则在连接时会出现错误

java.io.EOFException 位于java.io.DataInputStream.readByte(未知源) 位于org.apache.activemq.transport.stomp.StompWireFormat.unmarshal(StompWireFormat.java:137) 位于org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:77) 位于org.apache.activemq.transport.stomp.StompConnection.receive(StompConnection.java:68) 位于org.apache.activemq.transport.stomp.StompConnection.connect(StompConnection.java:139) 在…stomp.impl.activemq.ActiveMQStompDriver.connect(ActiveMQStompDriver.java:39) ... 25多

跟踪显示这是因为
CONNECT
frame从未收到预期的
CONNECTED
frame(实际上,它没有收到任何反馈)

所以我很困惑:我用错端口了吗?或者处理一些库不兼容?还是我需要以某种方式表明我想要Tomcat


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

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

开场握手旨在与基于HTTP的握手兼容 服务器端软件和中介,使单个端口可以 由与该服务器和WebSocket对话的HTTP客户端使用 与该服务器对话的客户端。为此,WebSocket客户端的 握手是一种HTTP升级请求

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

因此,请回答我自己的问题:

  • 图书馆必须支持开放式握手
  • 对于主机和端口,您需要指定Tomcat的主机(与RabbitMQ不同)和web端口(例如8080),而不是RabbitMQ端口
我最终使用了,这使得所有这些都非常容易。以下是最简单的设置:

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.
taskScheduler=new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(N);//N=线程数
taskScheduler.AfterPropertieSet();
stompClient=新WebSocketStompClient(新标准WebSocketClient());
setTaskScheduler(taskScheduler);
setMessageConverter(新的MappingJackson2MessageConverter());
WebSocketHttpHeaders握手头=新的WebSocketHttpHeaders();//您可以在这里为Tomcat添加额外的标题
//以下是其他图书馆缺失的主要部分:
//以下请求将同时执行握手和连接
//因此,它同时获得两组头文件(对于Tomcat和Stomp)
ListenableFuture future=stompClient.connect(
网址,
握手者,
新的StompHeaders(),
新的CustomStompSessionHandlerAdapter(this));//从实现CustomStompSessionHandlerAdapter的类调用,但这也可以是单独的类。
也看到

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.