8

Web 上似乎很少有 Java 11(纯 Java 非基于框架的)WebSocket客户端代码示例,所以我希望 StackOverflow 可以再次为我提供帮助。

是我发现的最接近的,但不幸的是,在我的(新手)眼中,它似乎不是展示如何使用来自 WebSocket 侦听器的数据的完整解决方案。

查看WebSocket.Listener 实现,我认为 onText回调方法将提供我需要的东西,但我正在努力弄清楚如何从套接字返回 CompletionStage 对象和某种字符串数据。

这是我到目前为止的一些测试代码。

将不胜感激帮助。谢谢

    public class Main {

        public static void main(String[] args) {

           WebSocketClient wsc = new WebSocketClient();
           wsc.startSocket("ws://demos.kaazing.com/echo");

           int i = 0;   

           // Bad, very bad
           do {} while (i == 0);
        }
    }


    public class WebSocketClient implements WebSocket.Listener {

        @Override
        public void onOpen(WebSocket webSocket) {
           //...
            System.out.println("Go...Open".concat(
                    webSocket.getSubprotocol()));
        }

        @Override
        public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
           //...
            System.out.println(data.toString());

            // How do I return the CompletionStage object
            // return CompletionStage<String>
        }

        @Override
        public void onError(WebSocket webSocket, Throwable error) {
           //..
            System.out.println("Bad day! ".concat(webSocket.toString()));
        }

        void startSocket(String connection) {
            CompletableFuture<WebSocket> server_cf = HttpClient.
                    newHttpClient().
                    newWebSocketBuilder().
                    buildAsync(URI.create(connection),
                            new WebSocketClient());
            WebSocket server = server_cf.join();
            server.sendText("Hello!", true);
        }
    }
4

2 回答 2

12

您可以在下面找到一个工作示例。我对上面的代码进行了一些更改:

  • onOpen需要request(1)在 websocket 上调用(调用默认实现)以接收进一步的调用。
  • 将方法startSocket移入主方法
  • 用倒计时锁代替忙等待
  • 将类声明WebSocketClient为(静态)内部类

但除了这些(化妆品)更改之外,程序会遵循您的想法,即首先构建一个 websocket 连接,成功构建后文本Hello!被发送到回显服务器。这也可以onOpen直接在方法中完成。

    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.WebSocket;
    import java.util.concurrent.CompletionStage;
    import java.util.concurrent.CountDownLatch;

    public class Main {

        public static void main(String[] args) throws Exception {
            CountDownLatch latch = new CountDownLatch(1);

            WebSocket ws = HttpClient
                    .newHttpClient()
                    .newWebSocketBuilder()
                    .buildAsync(URI.create("ws://demos.kaazing.com/echo"), new WebSocketClient(latch))
                    .join();
            ws.sendText("Hello!", true);
            latch.await();
        }

        private static class WebSocketClient implements WebSocket.Listener {
            private final CountDownLatch latch;

            public WebSocketClient(CountDownLatch latch) { this.latch = latch; }

            @Override
            public void onOpen(WebSocket webSocket) {
                System.out.println("onOpen using subprotocol " + webSocket.getSubprotocol());
                WebSocket.Listener.super.onOpen(webSocket);
            }

            @Override
            public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
                System.out.println("onText received " + data);
                latch.countDown();
                return WebSocket.Listener.super.onText(webSocket, data, last);
            }

            @Override
            public void onError(WebSocket webSocket, Throwable error) {
                System.out.println("Bad day! " + webSocket.toString());
                WebSocket.Listener.super.onError(webSocket, error);
            }
        }
    }

顺便说一句,没有协商 supprotocol,因此方法webSocket.getSubprotocol()返回一个空字符串。控制台中的输出是

    onOpen using subprotocol 
    onText received Hello!
于 2019-04-01T22:13:45.770 回答
0

管理返回 a 的 WebSocket 响应的模式CompletionStage是:

@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
    // return inmmediately but response is geenrated lazyly.
    return CompletableFuture.supplyAsync(() -> {
        String response = "Received  ...";
        // do slow task. Access to database or access to a server.
        return response;
    });
}

仅在快速生成响应时才建议使用这种简单的实现。

@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
    // fast response.
    String response = "The text has " + data.length() + " chars";
    return CompletableFuture.completedFuture(response);
}
于 2021-11-03T13:49:07.620 回答