2016-11-21 15 views
0

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

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

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

{"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, но я не знаю, как я могу передать это родительскому методу для ret Урн только что вернул ResponseEntity.ok().

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

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

+0

У вашего контроллера есть метод init? – nandsito

+0

Он имеет аннотацию '@ PostContruct'. – sebastian

ответ

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

Можете ли вы объяснить немного больше? Ожидание вашего обновленного ответа. – sebastian

+0

@sebastian теперь я понял проблему лучше, она немного сложнее, чем я думал раньше. Для этого потребуется некоторая синхронизация потоков. Используете ли вы tyrus как реализацию websocket? – nandsito

+0

Нет, я использую только javax.websocket. *. Микросервис не разработан мной, поэтому я не могу определить, что используется на стороне сервера. – sebastian