当前位置:   article > 正文

react中使用webscoket,封装webscoket类。_react websocket

react websocket

webscoket

服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

前端基础用法:

连接:

const ws = new Wenscoket('ws://xxxx')
这样就就会创建ws实例并且客户端就会与服务器进行连接。
ws.onopen=()=>{} //连接成功之后的监听
ws.onclose=()=>{} //连接失败或者关闭的回调
ws.onmessage=(data)=>{} //监听后端发送的信息
ws.onerror = ()=>{} //出错之后的回调。
ws.send(data)//向后端发送信息。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

后端基本用法(node)

const WebSocket = require("ws");
const path = require("path");
const wss = new WebSocket.Server({. //新建实例
  port: 9998,
});


  wss.on("connection", (client) => { //开启服务
    client.on("message", async (msg) => { //监听前端的发送数据,msg为前端发送回来
        client.send(JSON.stringify(payload)); //向后端发送数据
        //所有客户端 wss.clients,向所有连接客户端发送数据
        wss.clients.forEach((item) => {
            item.send(msg);
        });
      }
    });
  });


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

前端封装类

interface WebSocketDataParams {
  socketType: string;
  action: string;
  chartName: string;
  value: boolean;
}
interface WebSocketDataProps {
  socketType: string;
  action: string;
  chartName: string;
  value: boolean;
  data: string;
}

class SocketService {
  /**
   * 单例 保证拿到的都是同一个实例
   */
  static instance: SocketService;
  static get Instance() {
    if (!this.instance) {
      this.instance = new SocketService();
    }
    return this.instance;
  }

  baseUrl: string;
  ws: WebSocket;
  callBackMapping: Record<string, any>;
  isconnect: boolean;
  sendRetryCount: number; //重复发送次数
  connectRetryCount: number;
  constructor(url: string = "ws://localhost:9998") {
    this.baseUrl = url;
    this.ws = {} as WebSocket;
    this.callBackMapping = {};
    this.isconnect = false;
    this.sendRetryCount = 0;
    this.connectRetryCount = 0;
  }

  //和服务端创建的stocket对象

  //定义连接服务器的方法
  connect(url = "") {
    if (!window.WebSocket) {
      return console.log("您的浏览器不支持WebSocket");
    }
    url = url ? url : this.baseUrl;
    this.ws = new WebSocket(url);

    //连接监听
    this.ws.onopen = () => {
      console.log("连接服务端成功");
      this.connectRetryCount = 0;
      this.isconnect = true;
    };

    this.ws.onclose = () => {
      this.connectRetryCount++;
      console.log("连接失败/关闭");
      this.isconnect = false;
      //当连接关闭后进行重新连接尝试
      setTimeout(() => {
        this.connect();
      }, this.connectRetryCount * 500);
    };

    this.ws.onmessage = (res) => {
      const recvData: WebSocketDataProps = JSON.parse(res.data);
      const stocketType = recvData.socketType; //与后端约定type
      //如果存在,直接调用
      const callBack = this.callBackMapping[stocketType]; //执行订阅的回调
      if (callBack) {
        const action = recvData.action;
        if (action === "getData") {
          const realData = JSON.parse(recvData.data);
          //将数据传给回调函数
          callBack.call(this, realData);
        } else if (action === "fullScreen") {
        } else if (action === "themeChange") {
        }
      }
    };
  }

  //注册回调函数,可能有多个scoket
  registerCallBack(
    socketType: string,
    callBack: (data: Record<string, any>) => void
  ) {
    this.callBackMapping[socketType] = callBack;
  }

  unRegisterCallBack(socketType: string) {
    this.callBackMapping[socketType] = null;
  }

  send(data: WebSocketDataParams) {
    if (this.isconnect) {
      this.sendRetryCount = 0; //发送成功重置为0
      this.ws.send(JSON.stringify(data));
    } else {
      setTimeout(() => {
        this.sendRetryCount++;
        this.send(data);
      }, this.sendRetryCount * 500);
    }
  }
}
const wss = SocketService.Instance;
export { wss };

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113

采用封装类,然后可能会有多个页面需要使用到,所以采用派发订阅的模式
在这里插入图片描述
在这里插入图片描述
监听到数据的时候拿到对应的订阅函数执行。在这里插入图片描述
如,注册,然后记得注销掉。
这样一监听到后端返回来的数据就会执行回应的回调函数。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/770767
推荐阅读
相关标签
  

闽ICP备14008679号