记录一次websocket封装的过程

(编辑:jimmy 日期: 2024/11/9 浏览:2)

在一个应用中,websocket一般都是以单例形式存在的,即在整个应用中,websocket实例始终保持唯一。但有时我们要用到websocket实例的时候,可能websocket还没实例化,所以要做成异步的形式来获取实例。

一、封装。先创建 socket.ts 文件

import EventEmitter from 'events'; // 这里用到了 events 包
const ee = new EventEmitter();
class Ws {
 private wsUrl: string = '';
 private socket: WebSocket | undefined; // socket实例
 private lockReconnect: boolean = false; // 重连锁
 private timeout: NodeJS.Timeout | undefined;

 // 初始化socket,一般在应用启动时初始化一次就好了,或者需要更换wsUrl
 public init(wsUrl: string) {
  this.wsUrl = wsUrl;
  this.createWebSocket();
 }

 // 获取socket实例
 public getInstance(): Promise<WebSocket> {
  return new Promise((resolve, reject) => {
   if (this.socket) {
    resolve(this.socket);
   } else {
    ee.on('socket', (state: string) => {
     if (state === 'success') {
      resolve(this.socket);
     } else {
      reject();
     }
    });
   }
  });
 }

 // 创建socket
 private createWebSocket() {
  try {
   console.log('websocket 开始链接');
   const socket = new WebSocket(this.wsUrl);
   socket.addEventListener('close', () => {
    console.log('websocket 链接关闭');
    this.socket = undefined;
    this.reconnect();
   });
   socket.addEventListener('error', () => {
    console.log('websocket 发生异常了');
    this.socket = undefined;
    this.reconnect();
   });
   socket.addEventListener('open', () => {
    // 可在此进行心跳检测
    // this.heartCheck.start();
    console.log('websocket open');
    this.socket = socket;
    ee.emit('socket', 'success');
   });
   socket.addEventListener('message', (event) => {
    console.log('websocket 接收到消息', event);
   });
  } catch (e) {
   console.log('socket catch error', e);
   this.reconnect();
  }
 }

 // 重连
 private reconnect() {
  if (this.lockReconnect) {
   return;
  }
  console.log('websocket 正在重新连接');
  this.lockReconnect = true;
  //没连接上会一直重连,设置延迟避免请求过多
  this.timeout && clearTimeout(this.timeout);
  this.timeout = setTimeout(() => {
   this.createWebSocket();
   this.lockReconnect = false;
  }, 5000);
 }
}

export default new Ws();

二、引入并使用

import socket from '@/utils/ws';

socket
 .getInstance()
 .then((ws) => {
   // 这里的 ws 就是实例化后的 websocket,可以直接使用 websocket 原生 api
  console.log('getInstance ws', ws);
  ws.addEventListener('message', (event) => {
    console.log('ws 接收到消息', event);
   });
 })
 .catch(() => {});

以上就是记录一次websocket封装的过程的详细内容,更多关于websocket封装的资料请关注其它相关文章!

一句话新闻
微软与英特尔等合作伙伴联合定义“AI PC”:键盘需配有Copilot物理按键
几个月来,英特尔、微软、AMD和其它厂商都在共同推动“AI PC”的想法,朝着更多的AI功能迈进。在近日,英特尔在台北举行的开发者活动中,也宣布了关于AI PC加速计划、新的PC开发者计划和独立硬件供应商计划。
在此次发布会上,英特尔还发布了全新的全新的酷睿Ultra Meteor Lake NUC开发套件,以及联合微软等合作伙伴联合定义“AI PC”的定义标准。