zoukankan      html  css  js  c++  java
  • 前端WebSocket封装

    参考:https://www.jianshu.com/p/a4eacaf8de17

    一、只有单个长链接,不要求保活

    class WebSocketClass {
      constructor() {
        this.instance = null;
        this.connect();
      }
      static getInstance() {
        if (!this.instance) {
          this.instance = new WebSocketClass();
        }
        return this.instance;
      }
    
      connect() {
        this.ws = new WebSocket('ws://xxxxxx');
        this.ws.onopen = e => {
          this.status = 'open';
          console.log(`${name}连接成功`, e);
        };
      }
    
      getMessage() {
        this.ws.onmessage = e => {
          console.log(e.data);
          return e.data;
        };
      }
    
       close() {
        this.ws.send('close');
        this.ws.close();
        console.log('close');
      }
    }
    
    export default new WebSocketClass();

    二、多个长链接共存

    class WebSocketClass {
      constructor(name) {
        this.connect(name);
      }
    
      connect(name) {
        this.ws = new WebSocket(name);
        this.ws.onopen = e => {
          this.status = 'open';
          console.log(`${name}连接成功`, e);
        };
      }
    
      getMessage() {
        this.ws.onmessage = e => {
          console.log(e.data);
          return e.data;
        };
      }
    
      close() {
        this.ws.send('close');
        this.ws.close();
        console.log('close');
      }
    }
    
    export default WebSocketClass;

    关闭:这种情况就无法跨页面关闭了,只能在哪里开的在哪里关,不然是关不了的,拿不到创建的时候的ws长链接对象。

    三、保活

    保活的原理-->心跳,前端每隔一段时间发送一段约定好的message给后端,后端收到后返回一段约定好的message给前端,如果多久没收到前端就调用重连方法进行重连。

    import { message } from 'antd';
    
    class WebSocketClass {
      constructor() {
        this.instance = null;
        this.connect();
      }
      static getInstance() {
        if (!this.instance) {
          this.instance = new WebSocketClass();
        }
        return this.instance;
      }
    
      connect() {
        this.ws = new WebSocket('ws://xxxx');
        this.ws.onopen = e => {
          this.status = 'open';
          message.info('连接成功');
          console.log(`连接成功`, e);
          this.heartCheck();
          this.getMessage();
        };
      }
    
      heartCheck() {
        // 心跳机制的时间可以自己与后端约定
        this.pingPong = 'ping'; // ws的心跳机制状态值
        this.pingInterval = setInterval(() => {
          if (this.ws.readyState === 1) {
            // 检查ws为链接状态 才可发送
            this.ws.send('ping'); // 客户端发送ping
          }
        }, 10000);
        this.pongInterval = setInterval(() => {
          if (this.pingPong === 'ping') {
            this.closeHandle('pingPong没有改变为pong'); // 没有返回pong 重启webSocket
          }
          // 重置为ping 若下一次 ping 发送失败 或者pong返回失败(pingPong不会改成pong),将重启
          console.log('返回pong');
          this.pingPong = 'ping';
        }, 20000);
      }
    
      closeHandle(e = 'err') {
        // 因为webSocket并不稳定,规定只能手动关闭(调closeMyself方法),否则就重连
        if (this.status !== 'close') {
          console.log(`断开,重连websocket`, e);
          if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
            // 清除定时器
            clearInterval(this.pingInterval);
            clearInterval(this.pongInterval);
          }
          this.connect(); // 重连
        } else {
          console.log(`websocket手动关闭,或者正在连接`);
        }
      }
    
      getMessage() {
        this.ws.onmessage = e => {
          if (e.data === 'pong') {
            this.pingPong = 'pong'; // 服务器端返回pong,修改pingPong的状态
          } else {
            message.info(e.data);
          }
          console.log(e.data);
          return e.data;
        };
      }
    
      close() {
        clearInterval(this.pingInterval);
        clearInterval(this.pongInterval);
        this.status = 'close';
        this.ws.send('close');
        this.ws.close();
        message.info('已断开连接');
        console.log('close');
      }
    }
    
    export default new WebSocketClass();
  • 相关阅读:
    阿里云提示Discuz memcache+ssrf GETSHELL漏洞如何解决
    mysql总是无故退出, InnoDB: mmap(68681728 bytes) failed; errno 12
    ElasticSearch6 报错FORBIDDEN/12/index read-only / allow delete (api)
    Yum安装时提示多库版本保护 Multilib version problems found
    redis:CLUSTER cluster is down 解决方法
    虚拟主机如何绑定网站根目录到子目录中
    iscroll遇到的两个坑
    前端之Sass/Scss实战笔记
    JS与jquery书写插件规范
    css命名推荐
  • 原文地址:https://www.cnblogs.com/wfblog/p/14867018.html
Copyright © 2011-2022 走看看