Java Websocket / MessageHandler вернуться в глобальную область?

Я столкнулся со следующей проблемой и пока не нашел рабочего решения. У меня есть 3 разных приложения, которые должны общаться друг с другом:

  • часть пользовательского интерфейса (1)
  • бэкэнд-приложение (2)
  • микросервис "в облаке" (3)

Бэкэнд-приложение предоставляет веб-сервис (REST) ​​для пользовательского интерфейса для получения и передачи информации из / в микросервис. Все, что я хочу получить от микросервиса, работает нормально, но: если я хочу поместить данные в микросервис, спецификации требуют подключения через веб-сокет. Это тоже хорошо работает, но микросервис возвращает сообщение после (не) успешной команды, например

{"statusCode":200,"messageId":"1234567890"}

Теперь проблема заключается в следующем: как я могу получить это сообщение в своем приложении и отправить его обратно в пользовательский интерфейс, чтобы пользователь знал, была ли команда выполнена успешно?

На данный момент я попробовал это:

WebSocketClient.java

@OnMessage
public void onMessage(Session session, String msg) {
    if (this.messageHandler != null) {
        this.messageHandler.handleMessage(msg);
    }
}
public void addMessageHandler(MessageHandler msgHandler) {
    this.messageHandler = msgHandler;
}
public static interface MessageHandler {

    public String handleMessage(String message);
}

MyTotalAwesomeController.java

public class MyTotalAwesomeController {

    WebSocketClient wsc = new WebSocketClient();
    ...


    @RequestMapping(value="/add", method={RequestMethod.POST, RequestMethod.OPTIONS})
    public ResponseEntity<Object> putDataToMicroservice(@RequestBody Map<String, Object> payload, @RequestHeader(value = "authorization") String authorizationHeader) throws Exception {
    ...

    wsc.addMessageHandler(new WebSocketClient.MessageHandler() {
        public String handleMessage(String message) {

            System.out.println("RETURN MSG FROM WSS : " + message);
            return message;
        }
    });

    return ResponseEntity.ok("worked");
}

Я могу видеть консольный вывод из возврата MessageHandler, но я не знаю, как я могу передать это родительскому методу для возврата вместо простого возврата ResponseEntity.ok(),

Я еще не очень привык к соединениям WebSocket в Java, поэтому, пожалуйста, не судите меня;-)

Спасибо за помощь.

1 ответ

Решение

Код ниже будет работать при условии, что @OnMessage Метод выполняется в потоке, управляемом клиентской средой WebSocket. Пожалуйста, проверьте поток, который запускает @OnMessage метод.

Если вышеуказанная предпосылка верна, putDataToMicroservice() Метод, выполняемый потоком в глобальной области действия, будет ожидать поступления ответа WebSocket в поток клиента WS, который передаст сообщение в поток глобальной области действия. Затем выполнение в вашем классе контроллера будет продолжено.

public class MyTotalAwesomeController {

    WebSocketClient wsc = new WebSocketClient();

    // Queue for communication between threads.
    private BlockingQueue<String> queue;

    @PostConstruct
    void init() {

        queue = new SynchronousQueue<>(true);

        // This callback will be invoked by the WebSocket thread.
        wsc.addMessageHandler(new WebSocketClient.MessageHandler() {
            @Override
            public String handleMessage(String message) {
                System.out.println("RETURN MSG FROM WSS : " + message);
                // Pass message to the controller thread.
                queue.put(message);
                // Note that the return value is not necessary.
                // You can take it out of the interface as well.
                return null;
            }
        });
    }

    @RequestMapping(value="/add", method={RequestMethod.POST, RequestMethod.OPTIONS})
    public ResponseEntity<Object> putDataToMicroservice(@RequestBody Map<String, Object> payload, @RequestHeader(value = "authorization") String authorizationHeader) throws Exception {

        // At this point you make a WebSocket request, is that right?
        doWebSocketRequest();

        // This poll call will block the current thread
        // until the WebSocket server responds,
        // or gives up waiting after the specified timeout.
        //
        // When the WebSocket server delivers a response,
        // the WS client implementation will execute the
        // @OnMessage annotated method in a thread
        // managed by the WS client itself.
        //
        // The @OnMessage method will pass the message
        // to this thread in the queue below.

        String message = queue.poll(30, TimeUnit.SECONDS);

        if (message == null) {
            // WebSocket timeout.
        }

        return ResponseEntity.ok("worked");
    }
}
Другие вопросы по тегам