未收到Spring消息/ActiveMQ确认消息
我已经在这个问题上工作了一段时间,决定寻求一些帮助 我有下面的场景。在端口61614上侦听的ActiveMQ服务器。两个WebSocketStompClient正在连接到以下队列 客户1: /队列/请求/服务器1-/queue/replyto/server1 客户2: /队列/请求/服务器2-/queue/replyto/server2 这两台服务器相互通信并请求信息。 我对这些场景没有问题。 将请求从服务器1发送到服务器2队列,并在服务器1响应队列上接收响应 有点像这样: 此处执行的随机应用程序逻辑 但是,如果在响应第一个请求之前尝试向服务器1的请求队列发送另一条消息,则会出现问题。响应被发送到服务器2的响应队列,但从未收到 图片如下: 我希望它足够清楚,如果需要更多的解释请告诉我 其他信息是,我确信消息是在写入队列时发送的,并且我可以看到它 正如您还可以看到的,所有消息都已出列/确认 值得一提的是,所有这些都是通过docker ActiveMQ服务器和模拟开发服务器上发生的情况的单元测试在本地完成的 通过Wireshark,我可以看到消息已被server2确认 最后: 这是设置,两台服务器的设置相同: 客户:未收到Spring消息/ActiveMQ确认消息,spring,activemq,spring-websocket,spring-messaging,Spring,Activemq,Spring Websocket,Spring Messaging,我已经在这个问题上工作了一段时间,决定寻求一些帮助 我有下面的场景。在端口61614上侦听的ActiveMQ服务器。两个WebSocketStompClient正在连接到以下队列 客户1: /队列/请求/服务器1-/queue/replyto/server1 客户2: /队列/请求/服务器2-/queue/replyto/server2 这两台服务器相互通信并请求信息。 我对这些场景没有问题。 将请求从服务器1发送到服务器2队列,并在服务器1响应队列上接收响应 有点像这样: 此处执行的随机应用程
WebSocketClient transport = new StandardWebSocketClient();
WebSocketStompClient server1 = new WebSocketStompClient(transport);
server1.setMessageConverter(new MappingJackson2MessageConverter());
server1.setTaskScheduler(taskScheduler);
server1.setDefaultHeartbeat(heartbeat);
server1.connect(bindAddress, Server1SessionHandler);
处理程序:
public class Server1SessionHandler extends StompSessionHandlerAdapter {
@Override
public void afterConnected(final StompSession session, final StompHeaders connectedHeaders) {
logger.debug("Entering RemoteSessionHandler after connected method");
this.stompSession = session;
if (session.isConnected()) {
session.setAutoReceipt(true);
logger.trace("Attempting to subscribe to channel {} using the RequestFrameHandler ", this.subscribeChannel);
session.subscribe(this.subscribeChannel, new Server1RequestFrameHandler(session, null, brokerMessageTtl, logicService, guid));
logger.trace("Attempting to subscribe to channel {} using the ResponseFrameHandler ", this.replyQueue);
session.subscribe(this.replyQueue, new Server1ResponseFrameHandler(this.cache));
publisher.publishEvent(new ConnectionSuccessEvent(Server1SessionHandler.class, "RemoteSessionHandler"));
}
else {
logger.error("Could not connect to stomp Session {}", session.toString());
}
}
}
请求帧处理程序:
public class Server1RequestFrameHandler implements StompFrameHandler {
private StompSession session;
public Server1RequestFrameHandler(final StompSession session) {
this.session = session;
}
@Override
@SuppressWarnings("static-access")
public void handleFrame(final StompHeaders headers, final Object payload) {
...... BUSINESS LOGIC ......
if (session.isConnected()) {
session.send(header, response);
logger.debug("Successfully connected using the stompsession {}, ", session.toString());
}
}
@Override
public Type getPayloadType(final StompHeaders headers) {
return Request.class;
}
}
响应帧处理程序:
public class Server1ResponseFrameHandler implements StompFrameHandler {
private Server1Cache cache;
public Server1ResponseFrameHandler(final Server1Cache cache) {
this.cache = cache;
}
public void handleFrame(final StompHeaders headers, final Object payload) {
Response response = (Response) payload;
logger.debug("response: {}", response);
cache.cacheMessage(id, response);
}
public Type getPayloadType(final StompHeaders headers) {
return Response.class;
}
}
如果您需要更多信息,请告诉我 我可以通过订阅带有两种不同WebSocket连接设置的主题来绕过这个问题。例如: 创建一个请求客户端
WebSocketClient requestTransport = new StandardWebSocketClient();
WebSocketStompClient requestClient = new WebSocketStompClient(requestTransport);
requestClient.setMessageConverter(new MappingJackson2MessageConverter());
requestClient.setTaskScheduler(taskScheduler);
requestClient.setDefaultHeartbeat(heartbeat);
requestClient.connect(bindAddress, RequestSessionHandler);
创建一个单独的响应客户端
WebSocketClient responseTransport = new StandardWebSocketClient();
WebSocketStompClient responseClient = new WebSocketStompClient(responseTransport);
responseClient.setMessageConverter(new MappingJackson2MessageConverter());
responseClient.setTaskScheduler(taskScheduler);
responseClient.setDefaultHeartbeat(heartbeat);
responseClient.connect(bindAddress, ResponseSessionHandler);
其中,请求和响应会话处理程序仅订阅1个队列,而不是同时订阅这两个队列
public class RequestSessionHandler extends StompSessionHandlerAdapter {
@Override
public void afterConnected(final StompSession session, final StompHeaders connectedHeaders) {
...
if (session.isConnected()) {
session.subscribe("requestChannel", new Server1RequestFrameHandler(session, null, brokerMessageTtl, logicService, guid));
....
}
}
}
如果有人能解释为什么在只使用一个WebSocket客户端订阅两个队列时会发生这种情况,我很想听听
我的理论是,为websocket连接提供服务的线程忙于处理请求,无法自由处理发送的响应
WebSocketClient requestTransport = new StandardWebSocketClient();
WebSocketStompClient requestClient = new WebSocketStompClient(requestTransport);
requestClient.setMessageConverter(new MappingJackson2MessageConverter());
requestClient.setTaskScheduler(taskScheduler);
requestClient.setDefaultHeartbeat(heartbeat);
requestClient.connect(bindAddress, RequestSessionHandler);
WebSocketClient responseTransport = new StandardWebSocketClient();
WebSocketStompClient responseClient = new WebSocketStompClient(responseTransport);
responseClient.setMessageConverter(new MappingJackson2MessageConverter());
responseClient.setTaskScheduler(taskScheduler);
responseClient.setDefaultHeartbeat(heartbeat);
responseClient.connect(bindAddress, ResponseSessionHandler);
public class RequestSessionHandler extends StompSessionHandlerAdapter {
@Override
public void afterConnected(final StompSession session, final StompHeaders connectedHeaders) {
...
if (session.isConnected()) {
session.subscribe("requestChannel", new Server1RequestFrameHandler(session, null, brokerMessageTtl, logicService, guid));
....
}
}
}