1. 程式人生 > 程式設計 >記錄一次websocket封裝的過程

記錄一次websocket封裝的過程

在一個應用中,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封裝的資料請關注我們其它相關文章!