react使用websocket实时通信方式

目录
  • 使用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);

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 在Asp.net core项目中使用WebSocket

    今天小试了一下在Asp.net core中使用websocket,这里记录一下: 在 Startup 类的 Configure 方法中添加 WebSocket 中间件. app.UseWebSockets(); 它也可以传入一些参数 app.UseWebSockets(new WebSocketOptions() { KeepAliveInterval = TimeSpan.FromSeconds(120), ReceiveBufferSize = 4 * 1024 }); 添加WebSocke

  • SpringBoot+WebSocket实现消息推送功能

    目录 背景 WebSocket简介 协议原理 WebSocket与HTTP协议的区别 WebSocket特点 应用场景 系统集成Websocket jar包引入 Websocket配置 具体实现 测试示例 页面请求websocket 测试效果 背景 项目中经常会用到消息推送功能,关于推送技术的实现,我们通常会联想到轮询.comet长连接技术,虽然这些技术能够实现,但是需要反复连接,对于服务资源消耗过大,随着技术的发展,HtML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够

  • C++ Thread实现简单的socket多线程通信

    目录 起因 服务端 ROS客户端 普通客户端 运行效果 不足 起因 为什么要用C++的Thread,很简单,因为我菜 一打五用pthread实现了socket多线程通信,我之前学并发的时候没看pthread,因此代码只能看个大概,后面还是要系统学一下pthread的 服务端 多线程功能放在腾讯云服务器上,代码如下: #include "tcpserver.h" #include <thread> #include <mutex> TcpServer server

  • C#使用WebSocket与网页实时通信的实现示例

    目的:使用Fleck框架实现网页与服务端实时通信 传统的网站采用http方式与服务端通信,属于请求响应模式,如何让网页与服务器之间能使用TCP这种双向通信方式实时交流,答案就是使用WebSocket技术. Fleck框架的安装方式: 1.使用NuGet包管理工具安装 Install-Package Fleck -Version 1.2.0 2.下载Fleck源码并编译程序集供服务端引用 github地址:https://github.com/statianzo/Fleck/archive/ref

  • socket编程之bind()函数使用示例详解

    目录 正文 端口号具体是怎么绑定 老代码 端口被占用的问题解决 正文 当你创建了socket之后,你会想要把这个socket和你本机上的某个端口号(port)进行关联. 端口号是内核用来确认将收到的数据包交给哪个具体进程的socket descriptor的依据. 通常在写服务端程序的时候我们才需要进行关联,客户端程序不需要我们手动绑定端口,直接connect()就好了. 端口号具体是怎么绑定 #include <sys/types.h> #include <sys/socket.h&g

  • C++用winapi socket实现局域网语音通话功能

    目录 一.socket通信 二.waveIn和WaveOut的Win32API 1.音频设备的的信息获取 2.音频设备的初始化 3.输入输出设备缓冲区的准备和添加 4.播放和录音的开始和终止 5.录音通知消息的获取和处理 6.关闭音频输入和输出设备 三.通信数据包的设计以及客户端服务器逻辑 前几天看书了解了语音通话的原理,就很想自己尝试一下,然后就——做出来了,嘻嘻,先看看效果吧! 因为这边没办法上传视频,所以只能录制一个gif大家看一下效果,但是是可以听到声音的. 源码下载链接:http://

  • react使用websocket实时通信方式

    目录 使用websocket实时通信 创建公共组件 在react组件中的使用 websocket在不同情形下的使用 1.在react中使用websocket 2.websocket在小程序中使用 使用websocket实时通信 在react中使用websocket不需要引入其他库,只需要创建一个公共组件,封装一下websocket 创建公共组件 websocket.js let websocket, lockReconnect = false; let createWebSocket = (ur

  • nodejs+websocket实时聊天系统改进版

    本文属于nodejs+websocket实时聊天系统的改进版本,具体内容如下 自己也是真的菜,一个websocket简单聊天系统硬被我搞了那么些天. 看来以后还是得写更多的代码. client.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content=&q

  • php实现websocket实时消息推送

    php实现websocket实时消息推送,供大家参考,具体内容如下 SocketService.php <?php /** * Created by xwx * Date: 2017/10/18 * Time: 14:33 */ class SocketService { private $address = '0.0.0.0'; private $port = 8083; private $_sockets; public function __construct($address = '',

  • 基于spring实现websocket实时推送实例

    基于spring框架来写的,websocket实时推送例子,具体内容如下 第一步:自己搭建一个springmvc项目,很简单,网上百度都有:pom文件添加以下: <!-- WebSocket --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.2.4.RELE

  • 微信小程序使用GoEasy实现websocket实时通讯

    不需要下载安装,便可以在微信好友.微信群之间快速的转发,用户只需要扫码或者在微信里点击,就可以立即运行,有着近似APP的用户体验,使得微信小程序成为全民热爱的好东西~ 同时因为微信小程序使用的是Javascript语法,对前端开发人员而言,几乎是没有学习成本和技术门槛的.对于大部分场景,都可以使用小程序快速开发实现,不论是开发周期还是开发成本都低的让人笑哭,所以受到了技术开发团队的各种追捧~ 但如果要在小程序里快速的实现一个即时通讯功能,就有点尴尬,因为微信官方提供的只是一个底层的websock

  • js实现mp3录音通过websocket实时传送+简易波形图效果

    波形图:https://www.jb51.net/article/188545.htm 废话:想不到我的第一篇博客是关于前端,作为一名后端的小菜,前端方面肯定还有很多不足之处,如果文章有任何问题欢迎指正.感谢大家.好了!废话不多说下面讲一下需求. 需求:公司要求实现web端的录音并通过websocket实时上传至java后台,而且能通过vlc实时播放,简单一点讲就是我用网页在那一边讲话,一个大喇叭就能实时把我的话播出去,这样是不是通俗易懂呀,而且呢公司要求用mp3格式.当然啦!为了知道自己在讲话

  • 微信小程序通过websocket实时语音识别的实现代码

    之前在研究百度的实时语音识别,并应用到了微信小程序中,写篇文章分享一下. 先看看完成的效果吧 前置条件 申请百度实时语音识别key 百度AI接入指南 创建小程序 设置小程序录音参数 在index.js中输入 const recorderManager = wx.getRecorderManager() const recorderConfig = { duration: 600000, frameSize: 5, //指定当录音大小达到5KB时触发onFrameRecorded format:

  • React+高德地图实时获取经纬度,定位地址

    目录 1. 初始化地图 2. 地图扎点 3. 开启定位 4. 监听地图变化 5. 获取详细地址 6. 扎点动画

  • SpringBoot WebSocket实时监控异常的详细流程

    目录 写在前面 实现: 前端: 后端: 测试 写在前面 此异常非彼异常,标题所说的异常是业务上的异常. 最近做了一个需求,消防的设备巡检,如果巡检发现异常,通过手机端提交,后台的实时监控页面实时获取到该设备的信息及位置,然后安排员工去处理. 因为需要服务端主动向客户端发送消息,所以很容易的就想到了用WebSocket来实现这一功能. WebSocket就不做介绍了,上链接:https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket 前端略

  • react开发教程之React 组件之间的通信方式

    这两天学习了React感觉组件通信这个地方知识点挺多的,而且很重要,所以,今天添加一点小笔记. 父子组件通讯 通讯手段 这是最常见的通信方式,父组件只需要将子组件需要的props传给子组件,子组件直接通过this.props来使用. 通讯内容 更多要提的是如何合理的设置子组件的props,要想将子组件设计成一个复用性强的通用组件,需要将能够复用的部分抽象出来,抽象出来的props有两种形成,一种是简单的变量,另一种是抽象出来处理某种逻辑函数. 以Header 组件为例 //HeaderBar.j

随机推荐