Java - WebSocket получает ответ вне слушателя - PullRequest
0 голосов
/ 27 ноября 2018

Я не могу понять эту проблему.У меня есть 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;
}

Спасибо!

1 Ответ

0 голосов
/ 27 ноября 2018

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

Класс 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, но я надеюсь, что это поможет вам :).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...