Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
未收到Spring消息/ActiveMQ确认消息_Spring_Activemq_Spring Websocket_Spring Messaging - Fatal编程技术网

未收到Spring消息/ActiveMQ确认消息

未收到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响应队列上接收响应 有点像这样: 此处执行的随机应用程

我已经在这个问题上工作了一段时间,决定寻求一些帮助

我有下面的场景。在端口61614上侦听的ActiveMQ服务器。两个WebSocketStompClient正在连接到以下队列

客户1: /队列/请求/服务器1-/queue/replyto/server1

客户2: /队列/请求/服务器2-/queue/replyto/server2

这两台服务器相互通信并请求信息。 我对这些场景没有问题。 将请求从服务器1发送到服务器2队列,并在服务器1响应队列上接收响应

有点像这样:

此处执行的随机应用程序逻辑

但是,如果在响应第一个请求之前尝试向服务器1的请求队列发送另一条消息,则会出现问题。响应被发送到服务器2的响应队列,但从未收到

图片如下:

我希望它足够清楚,如果需要更多的解释请告诉我

其他信息是,我确信消息是在写入队列时发送的,并且我可以看到它

正如您还可以看到的,所有消息都已出列/确认

值得一提的是,所有这些都是通过docker ActiveMQ服务器和模拟开发服务器上发生的情况的单元测试在本地完成的

通过Wireshark,我可以看到消息已被server2确认

最后:

这是设置,两台服务器的设置相同:

客户:

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