欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

react使用websocket實時通信方式

 更新時間:2022年09月15日 11:45:08   作者:xffff00  
這篇文章主要介紹了react使用websocket實時通信方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

使用websocket實時通信

在react中使用websocket不需要引入其他庫,只需要創(chuàng)建一個公共組件,封裝一下websocket

創(chuàng)建公共組件

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 為服務(wù)端傳輸?shù)南?,在這里可以處理
? ? }
}
let reconnect = (url) => {
? ? if (lockReconnect) return;
? ? //沒連接上會一直重連,設(shè)置延遲避免請求過多
? ? 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 () {
? ? ? ? ? ? //這里發(fā)送一個心跳,后端收到后,返回一個心跳消息,
? ? ? ? ? ? //onmessage拿到返回的心跳就說明連接正常
? ? ? ? ? ? websocket.send("HeartBeat");
? ? ? ? }, this.timeout)
? ? }
}
//關(guān)閉連接
let closeWebSocket=()=> {
? ? websocket && websocket.close();
}
export {
? ? websocket,
? ? createWebSocket,
? ? closeWebSocket
};

在react組件中的使用

1.react 函數(shù)組件的使用

import {createWebSocket,closeWebSocket} from './websocket';
const Element=(param)=>{
?? ?useEffect(()=>{
?? ??? ?let url="";//服務(wù)端連接的url
?? ??? ?createWebSocket(url)
?? ??? ?//在組件卸載的時候,關(guān)閉連接
?? ??? ? return ()=>{
? ? ? ? ? ? closeWebSocket();
? ? ? ? }
?? ?})
}

2.react 類組件中的使用

import {createWebSocket,closeWebSocket} from './websocket';
....
componentDidMount(){
??? ?let url="";//服務(wù)端連接的url
?? ?createWebSocket(url)
?}
?componentWillUnmount(){
?? ? closeWebSocket();
}
....

如果一個連接,推送不同的消息如何處理?

1.需要安裝 pubsub-js

2.修改webscocket.js 獲取消息的代碼

import { PubSub } from 'pubsub-js';
...
?websocket.onmessage = function (event) {
? ? ? ? lockReconnect=true;
? ? ? ? //event 為服務(wù)端傳輸?shù)南?,在這里可以處理
? ? ? ? let data=JSON.parse(event.data);//把獲取到的消息處理成字典,方便后期使用
? ? ? ? PubSub.publish('message',data); //發(fā)布接收到的消息 'message' 為發(fā)布消息的名稱,data 為發(fā)布的消息
? ?}
? ?...

3.在組件中的使用

函數(shù)組件中的使用(在類組件中類似)

import { PubSub } from 'pubsub-js';
useEffect(()=>{
?? ?//訂閱 'message' 發(fā)布的發(fā)布的消息
?? ?messageSocket = PubSub.subscribe('message', function (topic,message) {?
?? ??? ?//message 為接收到的消息 ?這里進行業(yè)務(wù)處理
?? ?})
?? ?//卸載組件 取消訂閱
?? ?return ()=>{
? ? ? ? ? PubSub.unsubscribe(messageSocket);?
? ? }
}

websocket在不同情形下的使用

1.在react中使用websocket

在項目根目錄中創(chuàng)建一個websocket文件夾用于封裝公用組件

代碼如下:

/**
?* 參數(shù):[socketOpen|socketClose|socketMessage|socketError] = func,[socket連接成功時觸發(fā)|連接關(guān)閉|發(fā)送消息|連接錯誤]
?* 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;
? ? ? ? // 檢測返回的狀態(tài)碼 如果socket.readyState不等于1則連接失敗,關(guān)閉連接
? ? ? ? if(timeout) {
? ? ? ? ? ? let time = setTimeout(() => {
? ? ? ? ? ? ? ? ?if(this.socket && this.socket.readyState !== 1) {
? ? ? ? ? ? ? ? ? ? ?this.socket.close();
? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ?clearInterval(time);
? ? ? ? ? ? }, timeout);
? ? ? ? }
? ? };
? ? // 連接成功觸發(fā)
? ? onopen = () => {
? ? ? ? let {socketOpen} = this.param;
? ? ? ? this.isSucces=false ?//連接成功將標識符改為false
? ? ? ? socketOpen && socketOpen();
? ? };
? ? // 后端向前端推得數(shù)據(jù)
? ? onmessage = (msg) => {
? ? ? ? let {socketMessage} = this.param;
? ? ? ? socketMessage && socketMessage(msg);
? ? ? ? // 打印出后端推得數(shù)據(jù)
? ? ? ? console.log(msg);
? ? };
? ? // 關(guān)閉連接觸發(fā)
? ? onclose = (e) => {
? ? ? ? this.isSucces=true ? //關(guān)閉將標識符改為true
? ? ? ? console.log('關(guān)閉socket收到的數(shù)據(jù)');
? ? ? ? let {socketClose} = this.param;
? ? ? ? socketClose && socketClose(e);
? ? ? ? // 根據(jù)后端返回的狀態(tài)碼做操作
? ? ? ? // 我的項目是當前頁面打開兩個或者以上,就把當前以打開的socket關(guān)閉
? ? ? ? // 否則就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連接報錯觸發(fā)
? ? ? ? let {socketError} = this.param;
? ? ? ? this.socket = null;
? ? ? ? socketError && socketError(e);
? ? };
? ? sendMessage = (value) => {
? ? ? ? // 向后端發(fā)送數(shù)據(jù)
? ? ? ? if(this.socket) {
? ? ? ? ? ? this.socket.send(JSON.stringify(value));
? ? ? ? }
? ? };
};
export {
? ? webSocket,
? }

這樣就完成了websocket的全局功能組件封裝,在需要用的組件進行引用就行了

例:

import {webSocket} from "../../WebSocket/index";

//函數(shù)調(diào)用
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); ?//后端返回的數(shù)據(jù),渲染頁面
? ? ? ? ? ? ? ? // }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('連接建立成功');
? ? ? ? ? ? ? ? // 心跳機制 定時向后端發(fā)數(shù)據(jù)
? ? ? ? ? ? ? ? this.taskRemindInterval = setInterval(() => {
? ? ? ? ? ? ? ? ? ? this.socket.sendMessage({ "msgType": 0 })
? ? ? ? ? ? ? ? }, 30000)
? ? ? ? ? ? }
? ? ? ? });
    //重試創(chuàng)建socket連接
? ? ? ? try {
? ? ? ? ? ? this.socket.connection();
? ? ? ? } catch (e) {
? ? ? ? ? ? // 捕獲異常,防止js error
? ? ? ? ? ? // donothing
? ? ? ? }
? ? }

2.websocket在小程序中使用

小程序官方文檔里是有相關(guān)的組件和調(diào)用方法,所以這里就不詳細介紹了,簡單說一下我的理解和使用方法。

在項目根目錄下創(chuàng)建websocket文件

const app = getApp();
import { webSocketUrl } from '../utils/requst/url';
//websocket封裝模塊
const lqoWS = {
? openSocket(val) {
? ? let wsData = app.globalData.wsData;
? ? //我這里向后端傳參用的路徑參數(shù),所以這里稍微設(shè)置一下
? ? 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)
? ? ?})
? ? ?// 監(jiān)聽服務(wù)器推送的消息
? ? ?wx.onSocketMessage(message => {
? ? ? //把JSONStr轉(zhuǎn)為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)
? ? ? }
? ? ?})
? ?},
? ? ?
?//關(guān)閉信道
? ?closeSocket(val) {
? ? ?if (app.globalData.socketStatus == 'connected') {
? ? ? ?wx.closeSocket({
? ? ? ? ?success: () => {
? ? ? ? ? app.globalData.socketStatus = 'closeds'
? ? ? ? ?}
? ? ? ?})
? ? ?}
? ?},
? ? ?
? //發(fā)送消息函數(shù)
? ?sendMessage(val) {
? ? ?if (app.globalData.socketStatus == 'connected') {
? ? ?//自定義的發(fā)給后臺識別的參數(shù) ,我這里發(fā)送的是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,
}

使用

代碼里的相關(guān)參數(shù)需要在全局中進行設(shè)置

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);

小程序官方有非常詳細的使用說明。 

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • 在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解

    在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解

    這篇文章主要介紹了在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解,通過本文詳細步驟,您可以將 Auth0 集成到 React 項目并與后端服務(wù)交互,需要的朋友可以參考下
    2024-07-07
  • 從零開始搭建webpack+react開發(fā)環(huán)境的詳細步驟

    從零開始搭建webpack+react開發(fā)環(huán)境的詳細步驟

    這篇文章主要介紹了從零開始搭建webpack+react開發(fā)環(huán)境的詳細步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • React?SSR?中的限流案例詳解

    React?SSR?中的限流案例詳解

    這篇文章主要介紹了React?SSR?之限流,React SSR 畢竟涉及到了服務(wù)端,有很多服務(wù)端特有的問題需要考慮,而限流就是其中之一,本文會通過一個簡單的案例來說明,為什么服務(wù)端需要進行限流,需要的朋友可以參考下
    2022-07-07
  • React Hooks如何主動更新Hooks組件

    React Hooks如何主動更新Hooks組件

    這篇文章主要介紹了React Hooks如何主動更新Hooks組件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • React如何實現(xiàn)全屏監(jiān)聽Esc鍵

    React如何實現(xiàn)全屏監(jiān)聽Esc鍵

    這篇文章主要介紹了React如何實現(xiàn)全屏監(jiān)聽Esc鍵,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 解決React報錯Parameter 'props' implicitly has an 'any' type

    解決React報錯Parameter 'props' implicitly&nb

    這篇文章主要為大家介紹了React報錯Parameter 'props' implicitly has an 'any' type的解決處理方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 一文詳解如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)

    一文詳解如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)

    在現(xiàn)代Web應(yīng)用程序中,網(wǎng)絡(luò)連接是至關(guān)重要的,通過監(jiān)聽網(wǎng)絡(luò)狀態(tài),我們可以為用戶提供更好的體驗,例如在斷網(wǎng)時顯示有關(guān)網(wǎng)絡(luò)狀態(tài)的信息,本文將介紹如何使用React監(jiān)聽網(wǎng)絡(luò)狀態(tài)的變化,并提供相應(yīng)的代碼示例
    2023-06-06
  • Hello?React的組件化方式之React入門小案例演示

    Hello?React的組件化方式之React入門小案例演示

    這篇文章主要介紹了Hello?React的組件化方式-React入門小案例,本文通過Hello?React的案例,?來體驗一下React開發(fā)模式,?以及jsx的語法,需要的朋友可以參考下
    2022-10-10
  • React冒泡和阻止冒泡的應(yīng)用詳解

    React冒泡和阻止冒泡的應(yīng)用詳解

    這篇文章主要介紹了React冒泡和阻止冒泡的應(yīng)用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • VSCode搭建React Native環(huán)境

    VSCode搭建React Native環(huán)境

    這篇文章主要介紹了VSCode搭建React Native環(huán)境,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05

最新評論