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