首页 > 解决方案 > Java - WebSocket 在侦听器之外获取响应

问题描述

我无法弄清楚这个问题。我有一个 WebSocket,我想在 WebSocket 对象之外发出请求并获得响应,但我只能访问 WebSocket 对象侦听器内部的响应。

我可以在侦听器中完成所有逻辑,但我只想获取一个字符串并在主线程中处理它。

我使用nv-websocket-client作为我的 WebSocket 库。

这是我的示例代码:

WebSocket webSocket = new WebSocketFactory()
    .createSocket(URL, TIMEOUT)
    .addListener(new WebSocketAdapter(){
          @Override
          public void onTextMessage(WebSocket websocket, String text) throws Exception {
               super.onTextMessage(websocket, text);

               // TODO: pass result to function sendCommand()
          }
    })
    .connect()

public String sendCommand(String command) {
    webSocket.sendText(command);

    // TODO: return result;
}

谢谢!

标签: javawebsocket

解决方案


您要实现的基本上是等待异步操作完成然后返回给调用者。您将请求发送到服务器,但您无法知道答案何时会返回(如果有的话)。您正在使用的代码实现了信号完成的回调机制 - 这意味着无论何时发生某些事情(在您的情况下,您会收到来自服务器的响应),只需调用您在适配器中实现的方法。

CompletableFuture类是做这种事情的最佳人选。Future 是一个接口,用于获取可能在将来完成的结果。该.get()方法将阻塞调用线程,直到有结果可用。我的想法是创建一个自定义适配器,您将使用它来与服务器通信(发送数据和从中接收数据):

class MyWebSocketAdapter implements WebSocketAdapter {
   // Store the responseFuture as a member of the adapter. 
   private CompletableFuture<String> responseFuture;

   public String sendCommand(String command) {
       // CompletableFutures can only be "used" once, so create a new object
       responseFuture = new CompletableFuture<String>();
       webSocket.sendText(command);
       // Keep in mind potential errors and a timeout value to this call
       return responseFuture.get();
   }

   @Override
   public void onTextMessage(WebSocket websocket, String text) throws Exception {
      super.onTextMessage(websocket, text);
      // Do what you want to do with the text and then complete the future
      responseFuture.complete(text);
   }
}

但请注意,您需要为您创建的每个套接字创建一个新的适配器。如果将同一个对象传递给多个套接字,则会出现并发问题,因为只有一个套接字可以写入responseFuture.

另外,如果您不熟悉异步编程,我建议您阅读一下,它通常会使并发更易于管理,并且核心概念与语言无关,并且许多语言都有库或内置支持它。这里是java的介绍。


免责声明:我目前没有安装 Java IDE,所以我无法编译它,而且我已经有一段时间没有使用 Java,但我希望这对你有帮助:)。


推荐阅读