react 中 websocket 结合 pubsub 实现数据通信

一、react 中 websocket 结合 pubsub 实现数据通信

  1. react 中使用 websocket,创建 websocket.js 文件,需要下载 websocketpubsub-js,可以通过 npm i websocket pubsub-js -s 命令进行下载,引入 websocketw3cwebsocket 进行创建连接,引入 pubsub-jsPubSub 进行消息通信, 代码如下所示:
import { w3cwebsocket as W3CWebSocket } from 'websocket';
import { PubSub } from 'pubsub-js';
import { notification } from 'antd';

let websocket, lockReconnect = false;
  1. 创建 websocket 服务,通过 new W3CWebSocket 并且传入连接地址 urlwebsocket.onopen 连接服务并且心跳检测,websocket.onerror 服务出错并且重新连接,websocket.onclose 服务关闭,websocket.onmessage 接收消息并且处理消息,event 为服务端传输的消息,把获取到的消息处理成字典,通过 PubSub.publish 发布接收到的消息,message 为发布消息的名称,data 为发布的消息。reconnect 是连接 websocket,没连接上会一直重连,设置延迟避免请求过多。heartCheck 是心跳检查,websocket.send 这里发送一个心跳,后端收到后会返回一个心跳消息,onmessage 拿到返回的心跳就说明连接正常。closeWebSocket 是关闭 websocket 服务。handleWebsocketUrl 是处理 websocket 请求 urlnotificationInfowebsocket 信息提示框,代码如下所示:
import { w3cwebsocket as W3CWebSocket } from 'websocket';
import { PubSub } from 'pubsub-js';
import { notification } from 'antd';

const { pallasHostConf, getEnvDomain } = require('../../server/config/domainConf.js');
let websocket, lockReconnect = false;

// 创建 websocket 服务
let createWebSocket = (url) => {
  websocket = new W3CWebSocket(url);
  websocket.onopen = function () {
    heartCheck.reset().start();
  }
  websocket.onerror = function () {
    reconnect(url);
  };
  websocket.onclose = function (e) {
    console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
  }
  websocket.onmessage = function (event) {
    lockReconnect = true;
    let data = JSON.parse(event.data);
    console.log('event', event)
    PubSub.publish('warningMessage',data); 
  }
}

// 连接 websocket
let reconnect = (url) => {
  if (lockReconnect) return;
  setTimeout(function () {
    createWebSocket(url);
    lockReconnect = false;
  }, 4000);
}

// 心跳检查
let heartCheck = {
  timeout: 60000, 
  timeoutObj: null,
  reset: function () {
    clearInterval(this.timeoutObj);
    return this;
  },
  start: function () {
    this.timeoutObj = setInterval(function () {
      websocket.send("HeartBeat");
    }, this.timeout)
  }
}

// 关闭 websocket 服务
let closeWebSocket = () => {
  websocket && websocket.close();
}

// 处理 websocket 请求 url
let handleWebsocketUrl = (url) => {
  let handleUrl = '';
  const host = getEnvDomain(hostConf);
  if (host && host.includes('http')) {
    handleUrl = host.replace('http', 'ws');
    return handleUrl + url;
  } else if (host && host.includes('https')) {
    handleUrl = host.replace('https', 'ws');
    return handleUrl + url;
  } else {
    handleUrl = host;
    return handleUrl + url;
  }
}

// websocket 信息提示框
let notificationInfo = (type, message, description, duration) => {
  return notification[type]({
    message,
    description,
    duration,
  });
}

export {
  createWebSocket,
  closeWebSocket,
  handleWebsocketUrl,
  notificationInfo,
}
  1. react 中使用 websocket,引入上面的 websocket.js 文件,先声明 messageSocket ,在 componentDidMount 中创建 websocket 服务,window.onbeforeunload 用于监听页面关闭后 websocket 服务也关闭,PubSub.subscribe 订阅消息,PubSub.unsubscribe 取消订阅消息,代码如下所示:
let messageSocket = null;

componentDidMount() {
  createWebSocket(handleWebsocketUrl('/warning'));
  window.onbeforeunload = function() {
    closeWebSocket();
    PubSub.unsubscribe(messageSocket);
  }
}

componentDidUpdate(prevProps, prevState) {
  let _this = this;
  messageSocket = PubSub.subscribe('warningMessage', function (topic,message) { 
    _this.handleWarningMessage(message);
  });
 }
 
 componentDidUnMount() {
   closeWebSocket();
   PubSub.unsubscribe(messageSocket);
 }


版权声明:本文为weixin_42614080原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。