react使用websocket实时通信方式

Hana ·
更新时间:2024-11-13
· 213 次阅读

目录

使用websocket实时通信

创建公共组件

在react组件中的使用

websocket在不同情形下的使用

1.在react中使用websocket

2.websocket在小程序中使用

使用websocket实时通信

在react中使用websocket不需要引入其他库,只需要创建一个公共组件,封装一下websocket

创建公共组件

websocket.js

let websocket, lockReconnect = false; let createWebSocket = (url) => {     websocket = new WebSocket(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;         //event 为服务端传输的消息,在这里可以处理     } } let reconnect = (url) => {     if (lockReconnect) return;     //没连接上会一直重连,设置延迟避免请求过多     setTimeout(function () {         createWebSocket(url);         lockReconnect = false;     }, 4000); } let heartCheck = {     timeout: 60000, //60秒     timeoutObj: null,     reset: function () {         clearInterval(this.timeoutObj);         return this;     },     start: function () {         this.timeoutObj = setInterval(function () {             //这里发送一个心跳,后端收到后,返回一个心跳消息,             //onmessage拿到返回的心跳就说明连接正常             websocket.send("HeartBeat");         }, this.timeout)     } } //关闭连接 let closeWebSocket=()=> {     websocket && websocket.close(); } export {     websocket,     createWebSocket,     closeWebSocket }; 在react组件中的使用

1.react 函数组件的使用

import {createWebSocket,closeWebSocket} from './websocket'; const Element=(param)=>{     useEffect(()=>{         let url="";//服务端连接的url         createWebSocket(url)         //在组件卸载的时候,关闭连接          return ()=>{             closeWebSocket();         }     }) }

2.react 类组件中的使用

import {createWebSocket,closeWebSocket} from './websocket'; .... componentDidMount(){      let url="";//服务端连接的url     createWebSocket(url)  }  componentWillUnmount(){      closeWebSocket(); } ....

如果一个连接,推送不同的消息如何处理?

1.需要安装 pubsub-js

2.修改webscocket.js 获取消息的代码

import { PubSub } from 'pubsub-js'; ...  websocket.onmessage = function (event) {         lockReconnect=true;         //event 为服务端传输的消息,在这里可以处理         let data=JSON.parse(event.data);//把获取到的消息处理成字典,方便后期使用         PubSub.publish('message',data); //发布接收到的消息 'message' 为发布消息的名称,data 为发布的消息    }    ...

3.在组件中的使用

函数组件中的使用(在类组件中类似)

import { PubSub } from 'pubsub-js'; useEffect(()=>{     //订阅 'message' 发布的发布的消息     messageSocket = PubSub.subscribe('message', function (topic,message) {          //message 为接收到的消息  这里进行业务处理     })     //卸载组件 取消订阅     return ()=>{           PubSub.unsubscribe(messageSocket);      } } websocket在不同情形下的使用 1.在react中使用websocket

在项目根目录中创建一个websocket文件夹用于封装公用组件

代码如下:

/**  * 参数:[socketOpen|socketClose|socketMessage|socketError] = func,[socket连接成功时触发|连接关闭|发送消息|连接错误]  * timeout:连接超时时间  * @type {module.webSocket}  */ class webSocket {     constructor(param = {}) {         this.param = param;         this.reconnectCount = 0;         this.socket = null;         this.taskRemindInterval = null;         this.isSucces=true;     }     connection = () => {         let {socketUrl, timeout = 0} = this.param;         // 检测当前浏览器是什么浏览器来决定用什么socket         if ('WebSocket' in window) {             console.log('WebSocket');             this.socket = new WebSocket(socketUrl);         }         else if ('MozWebSocket' in window) {             console.log('MozWebSocket');             // this.socket = new MozWebSocket(socketUrl);         }         else {             console.log('SockJS');             // this.socket = new SockJS(socketUrl);         }         this.socket.onopen = this.onopen;         this.socket.onmessage = this.onmessage;         this.socket.onclose = this.onclose;         this.socket.onerror = this.onerror;         this.socket.sendMessage = this.sendMessage;         this.socket.closeSocket = this.closeSocket;         // 检测返回的状态码 如果socket.readyState不等于1则连接失败,关闭连接         if(timeout) {             let time = setTimeout(() => {                  if(this.socket && this.socket.readyState !== 1) {                      this.socket.close();                  }                  clearInterval(time);             }, timeout);         }     };     // 连接成功触发     onopen = () => {         let {socketOpen} = this.param;         this.isSucces=false  //连接成功将标识符改为false         socketOpen && socketOpen();     };     // 后端向前端推得数据     onmessage = (msg) => {         let {socketMessage} = this.param;         socketMessage && socketMessage(msg);         // 打印出后端推得数据         console.log(msg);     };     // 关闭连接触发     onclose = (e) => {         this.isSucces=true   //关闭将标识符改为true         console.log('关闭socket收到的数据');         let {socketClose} = this.param;         socketClose && socketClose(e);         // 根据后端返回的状态码做操作         // 我的项目是当前页面打开两个或者以上,就把当前以打开的socket关闭         // 否则就20秒重连一次,直到重连成功为止          if(e.code=='4500'){             this.socket.close();         }else{             this.taskRemindInterval = setInterval(()=>{                 if(this.isSucces){                     this.connection();                 }else{                     clearInterval(this.taskRemindInterval)                 }             },20000)         }     };     onerror = (e) => {         // socket连接报错触发         let {socketError} = this.param;         this.socket = null;         socketError && socketError(e);     };     sendMessage = (value) => {         // 向后端发送数据         if(this.socket) {             this.socket.send(JSON.stringify(value));         }     }; }; export {     webSocket,   }

这样就完成了websocket的全局功能组件封装,在需要用的组件进行引用就行了

例:

import {webSocket} from "../../WebSocket/index"; //函数调用 WebSocketTest=()=>{         //    判断专家是否登录         let that = this;         let userId = JSON.parse(localStorage.getItem("adminInfo")).id;         console.log(userId)         this.socket = new webSocket({             socketUrl: 'ws://xx.xxx.xxx/imserver/'+userId,             timeout: 5000,             socketMessage: (receive) => {                 console.log(receive)                 // if(receive.data === '1'){                 //     console.log(receive);  //后端返回的数据,渲染页面                 // }else if(JSON.parse(receive.data)){                 //     that.setState({msgData:receive.data})                 // }else{                 //     message.info("有新消息了")                 // }                 try {                     if (typeof JSON.parse(receive.data) == "object") {                         that.setState({msgData:receive.data})                     }else if(receive.data === '1'){                         console.log(receive.data);                     }                 } catch(e) {                     message.info(receive.data)                 }             },             socketClose: (msg) => {                 console.log(msg);             },             socketError: () => {                 console.log(this.state.taskStage + '连接建立失败');                 message.error("消息通信连接失败,建议刷新")             },             socketOpen: () => {                 console.log('连接建立成功');                 // 心跳机制 定时向后端发数据                 this.taskRemindInterval = setInterval(() => {                     this.socket.sendMessage({ "msgType": 0 })                 }, 30000)             }         });     //重试创建socket连接         try {             this.socket.connection();         } catch (e) {             // 捕获异常,防止js error             // donothing         }     } 2.websocket在小程序中使用

小程序官方文档里是有相关的组件和调用方法,所以这里就不详细介绍了,简单说一下我的理解和使用方法。

在项目根目录下创建websocket文件

const app = getApp(); import { webSocketUrl } from '../utils/requst/url'; //websocket封装模块 const lqoWS = {   openSocket(val) {     let wsData = app.globalData.wsData;     //我这里向后端传参用的路径参数,所以这里稍微设置一下     let urls = ''     if(val == '/userSocket/'){       urls = webSocketUrl + val + wsData.id     }     if(val == '/ownerSocket/'){       urls = webSocketUrl + val + wsData.id + '/' + wsData.lon + '/' + wsData.lat;     }     //打开时的动作      wx.onSocketOpen(() => {        console.log('WebSocket 已连接')        app.globalData.socketStatus = 'connected';        this.sendMessage(val);      })      //断开时的动作      wx.onSocketClose(() => {        console.log('WebSocket 已断开')        if(app.globalData.socketStatus == 'closeds'){         return       }        app.globalData.socketStatus = 'closed';        this.pdSocketOpen(val);      })      //报错时的动作      wx.onSocketError(error => {        console.error('socket error:', error)      })      // 监听服务器推送的消息      wx.onSocketMessage(message => {       //把JSONStr转为JSON       message = message.data.replace(" ", "");         if (typeof message != 'object') {             message = message.replace(/\ufeff/g, ""); //重点             var jj = JSON.parse(message);             message = jj;         }        console.log(message)      })      // 打开信道      wx.connectSocket({       url: urls,       success:(res)=>{         console.log(res)       }      })    },  //关闭信道    closeSocket(val) {      if (app.globalData.socketStatus == 'connected') {        wx.closeSocket({          success: () => {           app.globalData.socketStatus = 'closeds'          }        })      }    },   //发送消息函数    sendMessage(val) {      if (app.globalData.socketStatus == 'connected') {      //自定义的发给后台识别的参数 ,我这里发送的是name        wx.sendSocketMessage({         //  data: "{\"name\":\"" + '123' + "\"}"          data: app.globalData.wsData        })      }    },    pdSocketOpen (val) {     setTimeout(() => {       if(app.globalData.socketStatus == 'closed'){         // console.log(app.globalData.socketStatus)         this.openSocket(val);       }     }, 4000)   }, } export {   lqoWS, }

使用

代码里的相关参数需要在全局中进行设置

import { lqoWS } from '../../websoket/index'; let val = '/ownerSocket/';     if(app.globalData.socketStatus == 'closed'){         // that.openSocket();         lqoWS.openSocket(val);     }     // lqoWS.closeSocket(val);     lqoWS.sendMessage(val);     lqoWS.pdSocketOpen(val);

小程序官方有非常详细的使用说明。 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。 



通信方式 通信 websocket React

需要 登录 后方可回复, 如果你还没有账号请 注册新账号