2016-11-21 126 views
0

我正面臨以下問題,我發現還沒有工作解決方案。 我有應該彼此通信3個不同的應用:Java Websocket/MessageHandler返回全局範圍?

  • UI部分(1)
  • 後端應用程序(2)
  • 「雲」 的微服務(3)

後端應用程序爲UI提供了Web服務(REST),以便從微服務中獲取信息並將信息放入微服務。 我想從微服務中抓取的所有東西都可以正常工作,但是: 如果我想將數據放到微服務中,則需要Websocket連接。這工作也沒關係,但微服務的(未)成功命令後返回的消息,像

{"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()

我不是很習慣在Java的WebSocket連接還沒有,所以請不要對我做出判斷;-)

謝謝您的幫助。

+0

您的控制器是否有init方法? – nandsito

+0

它有'@ PostContruct'註釋。 – sebastian

回答

1

下面的代碼將在假設@OnMessage方法在由WebSocket客戶機運行時管理的線程中執行的情況下工作。請檢查運行@OnMessage方法的線程。

如果上述前提爲真,由全局作用域中的線程執行的putDataToMicroservice()方法將等待,直到WebSocket響應到達WS客戶端線程,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