Java如何同步读取WebSocket 数据

背景:在同步的web请求中,读取WebSocket 数据时,等待数据读取,并根据返回的结果,结束当前WebSocket连接。

CountDownLatch 是 Java 中用于线程间通信和同步的工具之一,它允许一个或多个线程等待其他线程完成操作后再继续执行。

利用 CountDownLatch 同步读取 WebSocket 数据的一般流程:

  1. 在主线程中初始化 CountDownLatch 对象,并指定等待的线程数量。
  2. 启动 WebSocket 客户端连接到 WebSocket 服务器。
  3. 启动一个单独的线程,用于读取 WebSocket 数据。
  4. 在读取数据的线程中,当接收到数据时,处理数据并调用 countDown() 方法来减少 CountDownLatch 的计数器。
  5. 在主线程中,调用 await() 方法来阻塞等待,直到所有数据都被读取完毕,即 CountDownLatch 的计数器减少到零。

这样可以确保在主线程中等待,直到所有的数据都被读取完毕,然后再继续执行其他操作。

java 复制代码
 Request wss = new Request.Builder()
                    .url(wss_url)
                    .build();

            CountDownLatch latch = new CountDownLatch(1);


            RespBean respBean = RespBean.build();
            WebSocketListener listener = new WebSocketListener() {


                @Override
                public void onMessage(WebSocket webSocket, String text) {
                    super.onMessage(webSocket, text);

                    if (text.startsWith("{") && text.endsWith("}")) {
                        JSONObject rps = JSON.parseObject(text);
                        String body = rps.getString("body");
                        String bodyText = new String(Base64.getDecoder().decode(body));
                        String trim = bodyText.substring(5).trim();
                        if (trim.startsWith("{") && trim.endsWith("}")) {
                            JSONObject data = JSON.parseObject(trim);
                            JSONObject message = data.getJSONObject("message");
                            if (message != null) {
                                String status = message.getString("status");
                                if ("finished_successfully".equals(status)) {
                                    respBean.setData(data);
                                    webSocket.close(1000, "数据接受完成");
                                    // 如果收到特定数据,则释放 CountDownLatch
                                    latch.countDown();

                                }
                            }
                        } else if ("[DONE]".equals(trim)) {
                            webSocket.close(1000, "数据接受完成");
                        }

                    }

                }

                @Override
                public void onMessage(WebSocket webSocket, ByteString bytes) {
                    super.onMessage(webSocket, bytes);
                    respBean.setData(bytes.hex());

                    System.out.println("Received bytes: " + bytes.hex());
                }

                @Override
                public void onFailure(WebSocket webSocket, Throwable t, Response response) {
                    super.onFailure(webSocket, t, response);
                    respBean.setStatus(500);
                    respBean.setData(t);

                    t.printStackTrace();
                }
            };

            RequestUtil.getOkHttpClient().newWebSocket(wss, listener);


            try {
                // 设置超时时间为30秒
                if (!latch.await(60, TimeUnit.SECONDS)) {
                    // 超时未收到特定数据,进行处理
                    log.info("Timeout: Did not receive specific data within 60 seconds.");
                } else {
                    // 收到特定数据,进行处理
                    log.info("Received specific data!");
                }
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
相关推荐
七夜zippoe24 分钟前
Rust `std::iter` 深度解析:`Iterator` Trait、适配器与性能
开发语言·算法·rust
靠沿30 分钟前
JavaSE知识分享——继承(下)
java·开发语言
Catfood_Eason42 分钟前
CMPP3020作业2
java·开发语言
CryptoRzz44 分钟前
印度实时股票数据源接口对接文档-IPO新股、k线数据
java·开发语言·数据库·区块链
宸津-代码粉碎机1 小时前
Java内部类内存泄露深度解析:原理、场景与根治方案(附GC引用链分析)
java·开发语言·jvm·人工智能·python
NEU-UUN1 小时前
C语言 . 第三章第二节 .递归函数
c语言·开发语言
weixin_307779131 小时前
Python编码规范之字符串规范修复程序详解
开发语言·python·代码规范
郝学胜-神的一滴1 小时前
深入理解 Python 的 __init_subclass__ 方法:自定义类行为的新方式 (Effective Python 第48条)
开发语言·python·程序人生·个人开发
東雪木1 小时前
Java基础语言进阶学习——1,JVM内存模型(堆、栈、方法区)
java·jvm·学习
毕设源码-郭学长1 小时前
【开题答辩全过程】以 常二社区线上养老院管理系统为例,包含答辩的问题和答案
java·eclipse