当前位置: 首页 > news >正文

React + ts 中应用 Web Work 中集成 WebSocket

一、Web Work定义

 useEffect(() => {let webSocketIndex  = -1const websocketWorker = new Worker(new URL('./websocketWorker.worker.ts?worker',             import.meta.url),{type: 'module' // 必须声明模块类型});//初始化WEBSOCKET(多个服务器选择最快建立连接的一个)const urls = (import.meta.env.VITE_WEB_SOCKET).split(',');for(const url of urls) {this.works.websocketWorker.postMessage({type: "INIT_WEBSOCKET", payload: {url: url}});}websocketWorker.onmessage = (e) => {//接收子线程消息//接收连接打开消息if(e.data.type === "OPEN") {//这里通过变量改变只使用一次opne选择最快反馈的服务器if(webSocketIndex === -1) {webSocketIndex = e.data.index;websocketWorker.postMessage({type: "SELECT_SOCKET", payload:e.data.index});}}};return () => {if(websocketWorker ) {websocketWorker.postMessage({ type: "CLOSE_WEBSOCKET" });const str = setTimeout(() => {websocketWorker .terminate()clearTimeout(str);}, 500);}};}, []);

二、子线程中WebSocket 的启动使用

let socket: WebSocket | null = null;
let sockets: WebSocket[] = [];
let pingTimer: NodeJS.Timeout | null = null;self.onmessage = (e) => {const message = e.data as MessageData;//webSocket 子进程switch(message.type) {//初始化webSocketcase "INIT_WEBSOCKET":const ws = new WebSocket(message.payload.url);sockets.push(ws);ws.onopen = () => self.postMessage({ type: 'OPEN', index: sockets.indexOf(ws) });return "";case "SELECT_SOCKET":socket = sockets[message.payload];// 发送Ping帧(心跳检测)pingTimer = setInterval(() => {(socket as WebSocket).send(new Uint8Array([0x89, 0x00])); }, PING_TIME);//消息队列先进先出const queue = new WebSocketQueue(socket);queue.listen((msg) => {console.log('SOCKET:', msg.timestamp, msg.data);});//其他socket连接关闭节省资源const otherSocket = sockets.filter((_, index) => index !== message.payload);for(const other of otherSocket) {other.close();}return "";   case "CLOSE_WEBSOCKET":if(socket) (socket as WebSocket).close();if(pingTimer) clearInterval(pingTimer);return "";     default:return "";         }};

三、补充(WebSocket 消息队列实现)

/*** WebSocket消息队列,先进先出*/
export class WebSocketQueue {private queue: {data: any, timestamp: number}[] = [];private messageHandler?: (msg: {data: any, timestamp: number}) => void;constructor(socket: WebSocket) {socket.onmessage = (ev) => {this.queue.push({data: ev.data, timestamp: Date.now()});this.messageHandler?.(this.queue.shift()!); // FIFO处理};}// 注册消息处理器public listen(handler: (msg: {data: any, timestamp: number}) => void) {this.messageHandler = handler;}
}

http://www.dtcms.com/a/292248.html

相关文章:

  • linux初识网络及UDP简单程序
  • 2025年母单脱焦虑计划:社交恐惧者的塔罗赋能训练营
  • leetcode 1695. 删除子数组的最大得分 中等
  • 二分查找-852.山峰数组的峰顶索引-力扣(LeetCode)
  • 力扣 hot100 Day52
  • LeetCode 633.平方数之和
  • XML高效处理类 - 专为Office文档XML处理优化
  • Mysql-场景篇-2-线上高频访问的Mysql表,如何在线修改表结构影响最小?-1--Mysql8.0版本后的INSTANT DDL方案(推荐)
  • 【MySQL】MySQL基本概念
  • NISP-PTE基础实操——命令执行
  • MySQL高可用主从复制原理及常见问题
  • mysql_innodb_cluster_metadata源数据库
  • n1 armbian docker compose 部署aipan mysql
  • 板凳-------Mysql cookbook学习 (十二--------5)
  • vue3实现高性能pdf预览器功能可行性方案及实践(pdfjs-dist5.x插件使用及自定义修改)
  • Redis高级篇之最佳实践
  • VUE 中父级组件使用JSON.stringify 序列化子组件传递循环引用错误
  • TDengine时序数据库 详解
  • 扣子Coze智能体实战:自动化拆解抖音对标账号,输出完整分析报告(喂饭级教程)
  • STM32-SPI全双工同步通信
  • 什么是分布式事务,分布式事务的解决方案有哪些?
  • PyTorch 模型开发全栈指南:从定义、修改到保存的完整闭环
  • 自编码器表征学习:重构误差与隐空间拓扑结构的深度解析
  • vue2.0 + elementui + i18n:实现多语言功能
  • 智能Agent场景实战指南 Day 18:Agent决策树与规划能力
  • SpringBoot+Mybatis+MySQL+Vue+ElementUI前后端分离版:权限管理(三)
  • Class10简洁实现
  • 图解Spring的循环依赖
  • 2025茶吧机语音控制集成方案
  • 深入解析Hadoop中的推测执行:原理、算法与策略