Websocket的简单封装——超实用

584 阅读2分钟

需求/功能

  1. 使用websocket能够监听服务端发送的数据并处理
  2. 能够注册监听事件
  3. 能够监听webSocket断开
  4. 全局只用到一个websocket对象,可多页面复用

设计思路

  1. 封装websocket类,并使用单例模式,全局只有一个Websocket对象
  2. 使用 reconnecting-websocket 监听websocket连接与断开

设计实现

useWebsocket.js - JS版本

/*
 * @Autor: pxt
 * @Description: websocket类封装  需要先npn install reconnecting-websocket
                使用 reconnecting-websocket 库 能够实现断线重连
 * @Documentation:  https://github.com/joewalnes/reconnecting-websocket
 * @Date: 2022-08-01 17:59:44
 * @LastEditTime: 2022-08-01 18:07:05
 */

import Rwebsocket from 'reconnecting-websocket';
class IWebsocket {
    constructor() {
        // 定义一个对象 用于接收websocket对象
        this.instance = null;
    }
    // 创建连接
    conectWebsocket(urlOut) {
        // 对webSocket连接创建回调
        return new Promise((resolve, reject) => {
            let url = urlOut || 'ws://localhost:8666';
            this.instance = new Rwebsocket(url);
            this.instance.onopen = (evt) => {
                console.log("websocket-连接成功", evt);
                resolve(evt);
            };
            this.instance.onclose = (evt) => {
                console.log("websocket-断开连接");
            };
            this.instance.onmessage = (evt) => {
                this.onMessageHandler(evt);
            };
            this.instance.onerror = (evt) => {
                // console.log(evt);
                console.log("websocket-连接错误");
                reject(evt);
            };
        });
    }
    //注册监听事件
    resgisterHandler(cb) {
        this.handler = cb;
    }
    // 清除注册事件
    clearHandler() {
        this.handler = () => { };
    }
    // 发送消息
    sendMessageHandler(data) {
        data = JSON.stringify(data);
        this.instance?.send(data);
    }
    // 消息事件监听
    onMessageHandler(evt) {
        try {
          const params = JSON.parse(evt.data);
          this.handler?.call(this, params);
        } catch (error) {
          this.handler?.call(this, evt.data);
        }
    }
    // 断开连接
    close() {
       this.instance?.close();
    }
}
export default new IWebsocket();

useWebsocket.ts - TS版本

/*
 * @Autor: pxt
 * @Description: websocket类封装  需要先npn install reconnecting-websocket
                使用 reconnecting-websocket 库 能够实现断线重连
 * @Documentation:  https://github.com/joewalnes/reconnecting-websocket
 * @Date: 2022-07-28 17:47:54
 * @LastEditTime: 2022-07-28 18:49:01
 */
import Rwebsocket from 'reconnecting-websocket'
class IWebsocket {
  // 定义一个对象 用于接收websocket对象
  public instance: Rwebsocket | null = null;
  // wenbsocket数据处理注册事件
  public handler?: (params: any) => void;
  constructor() {}
  // 创建连接
  conectWebsocket(urlOut?: string) {
    // 对webSocket连接创建回调
    return new Promise((resolve, reject) => {
      let url: string = urlOut || 'ws://localhost:8666';
      this.instance = new Rwebsocket(url);
      this.instance.onopen = (evt) => {
        console.log("websocket-连接成功",evt);
        resolve(evt);
      };
      this.instance.onclose = (evt) => {
        console.log("websocket-断开连接");
      };
      this.instance.onmessage = (evt) => {
        this.onMessageHandler(evt);
      };
      this.instance.onerror = (evt) => {
        // console.log(evt);
        console.log("websocket-连接错误");
        reject(evt)
      };
    })
  }
  //注册监听事件
  resgisterHandler(cb: (evt: MessageEvent<any>) => void) {
    this.handler = cb;
  }
  // 清除注册事件
  clearHandler() {
    this.handler = () => {};
  }
  // 发送消息
  sendMessageHandler(data: any) {
    data = JSON.stringify(data);
    this.instance?.send(data);
  }
  // 消息事件监听
  onMessageHandler(evt: MessageEvent<any>) {
    try {
      const params = JSON.parse(evt.data);
      this.handler?.call(this, params);
    } catch (error) {
       this.handler?.call(this, evt.data);
    }
  }
  // 断开连接
  close(){
    this.instance?.close();
  }
}
export default new IWebsocket();

项目使用

import IWebsocket from '@/utils/useWebsocket'

//连接WebSocket
function connect(){
  IWebsocket.conectWebsocket().then(()=>{
    console.log('连接成功')
  }).catch(err =>{
    console.log('连接失败',err);
  });
}

//注册监听事件
function resgister(){
    IWebsocket.resgisterHandler((str)=>{
        console.log('服务返回的数据',str);
  })
}

//给服务端发送数据
function sendData(){
    IWebsocket.sendMessageHandler('你好');
}

总结

使用单例模式,全局只会生成一个websocket实例,可实现多页面复用。注册的监听事件由handler对象接收而不是使用数组方式,方便了监听当前显示页面,但造成无法多个地方同时监听,如果需要同时监听的可以改造成数组接收的方式,参考观察者模式。 reconnecting-websocket 代替了心跳函数编写,更加简单方便