打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
webSocket通信js封装
userphoto

2023.02.03 湖南

关注

webSocket通信封装

一. js使用WebSocket介绍

二. webSocket js封装使用

三. js封装代码

一. js使用WebSocket介绍

1. 创建WebSocket实例

url:url之前需添加ws://(未加密)或wss://(已加密),类似http://、https://

protocol:与服务端定义的协议名称相同,协议的参数例如XMPP(Extensible Messaging and Presence Protocol)、SOAP(Simple Object Access Protocol)或者自定义协议

var ws = new WebSocket('ws://url');

var ws1 = new WebSocket('ws://url', 'myprotocol');

var ws2 = new WebSocket('ws://url', ['protocol_1','protovol_2']));

1

2

3

2.属性

①readyState属性:WebSocket当前连接状态

属性值 属性常量 描述

0 CONNECTING 正在与服务端建立WebSocket连接,还没有连接成功

1 OPEN 连接成功并打开,可以发送消息

2 CLOSING 进行关闭连接的操作,且尚未关闭

3 CLOSE 连接已关闭或不能打开

通过 ws.readyState属性查看当前连接状态

alert('ws连接状态:' + ws.readyState);

1

②bufferedAmount:检查传输数据的大小,当客户端传输大量数据时使用避免网络饱和

③protocol:在构造函数中使用,protocol参数让服务端知道客户端使用的WebSocket协议。而WebSocket对象的这个属性就是指的最终服务端确定下来的协议名称,可以为空

3. 方法

①发送数据:send()

②关闭连接:closed()

//发送数据

var message = {

id: 1,

title: '发送ws数据'

}

ws.send(JSON.stringify(message));    // 复杂的数据结构要先进行序列化

//关闭连接

ws.close()


4. 事件

WebSocket API是纯事件驱动,建立连接之后,可自动发送状态改变的数据和通知

事件值 描述

onopen 当建立websocket连接时触发,只触发一次

onerror 当连接出现错误时触发-因为当触发了onerror之后连接就会触发关闭事件

onmessage 当服务端发送数据时触发,可多次触发,页面数据展示处理模块–实现轮询

onclose 当websocket连接关闭时触发,只触发一次

使用示例

var ws = new WebSocket('ws://url');

// 获取连接状态

console.log('ws连接状态:' + ws.readyState);

//监听是否连接成功

ws.onopen = function () {

    console.log('ws连接状态:' + ws.readyState);

    //连接成功则发送一个数据

    ws.send('test1');

}

// 接听服务器发回的信息并处理展示

ws.onmessage = function (data) {

    console.log('接收到来自服务器的消息:');

    console.log(data);

    //完成通信后关闭WebSocket连接

    ws.close();

}

// 监听连接关闭事件

ws.onclose = function () {

    // 监听整个过程中websocket的状态

    console.log('ws连接状态:' + ws.readyState);

}

// 监听并处理error事件

ws.onerror = function (error) {

    console.log(error);

}


二. webSocket js封装使用

创建一个js文件, 代码在下, 最后将方法暴露出去, 使用的时候可以直接引用文件中的方法 调用, 或者 将该js文件挂载在vue的prototype中

直接引用文件 方法 调用

import {createWebSocket} from '@/utils/socket’

createWebSocket()

挂载在vue的prototype中

3. 整个项目只有一条webSocket通信:

① 在登录后即可创建webSocket通信, 接受的数据中可定义一个参数, 该参数来控制是 做什么功能

例如这里 :

“webSocket_device_transport” 是某一个界面需要实时添加的一些数据

“webSocket_device_alarm” 是一个全局提示弹框, 需要添加的数据

② 创建了 new Map(); key和value 用来一一对应发送和接受的数据

//思路

var globalCallback = new Map();  //创建 new Map()

globalCallback.set(key,callback);  //发送数据的时候, 要定义一个唯一的key 和后端返回的key是一一对应, 定义一个回调函数用来接收数据后处理数据

//例如上图片中 接收的数据 res.method == "webSocket_device_transport",  用sn作为唯一的标识符, 

// 客户端在发送数据时 globalCallback.set("sn",resultFunc),  通过globalCallback存了一个key为"sn"的回调函数,

// 然后通信接收的数据中 返回作为标识符的"sn", 用来查找存的回调函数, 然后处理数据.  (因为处理数据的方法可能有多种, 不唯一, 所以用回调函数)

const callback = globalCallback.get(ret.sn)

callback(ret);


三. js封装代码

import { getToken} from '@/utils/auth'

var websock = null;

let rec; //断线重连后,延迟5秒重新创建WebSocket连接  rec用来存储延迟请求的代码

let isConnect = false; //连接标识 避免重复连接

let checkMsg = "heartbeat"; //心跳发送/返回的信息 服务器和客户端收到的信息内容如果如下 就识别为心跳信息 不要做业务处理

var globalCallback = new Map();

let createWebSocket = () => {

  try {

    initWebSocket(); //初始化websocket连接

  } catch (e) {

    console.log("尝试创建连接失败");

    reConnect(); //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接

  }

};

//定义重连函数

let reConnect = () => {

  console.log("尝试重新连接");

  if (isConnect) return; //如果已经连上就不在重连了

  rec && clearTimeout(rec);

  rec = setTimeout(function () { // 延迟5秒重连  避免过多次过频繁请求重连

    createWebSocket();

  }, 5000);

};

//设置关闭连接

let closeWebSocket = () => {

  websock.close();

};

//心跳设置

var heartCheck = {

  timeout: 20000, //每段时间发送一次心跳包 这里设置为20s

  timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)

  start: function () {

    this.timeoutObj = setInterval(function () {

      console.log("hearting ....")

      if (isConnect) websock.send(checkMsg);

    }, this.timeout);

  },

  reset: function () {

    clearInterval(this.timeoutObj)

    this.start();

  },

  stop: function (){

    clearInterval(this.timeoutObj)

  }

};

// 初始化websocket

function initWebSocket() {

  // ws地址

  // const wsUri = "ws://10.27.100.151:5000/occpws/customWebSocket";

 const wsUri = "wss://cloudiot.notioni.com/ws/occpws/customWebSocket";

  websock = new WebSocket(wsUri,getToken())

  websock.onmessage = function (e) {

    websocketonmessage(e)

  }

  websock.onclose = function (e) {

    websocketclose(e)

  }

  websock.onopen = function () {

    websocketOpen()

    heartCheck.start();

  }

  // 连接发生错误的回调方法

  websock.onerror = function () {

    console.log('WebSocket连接发生错误')

    isConnect = false; //连接断开修改标识

    reConnect(); //连接错误 需要重连

  }

}

// 实际调用的方法

function sendSock(agentData, callback, key) {

  if (!websock){

    initWebSocket()

  }

  globalCallback.set(key,callback)

  if (websock.readyState === websock.OPEN) {

    // 若是ws开启状态

    websocketsend(agentData)

  } else if (websock.readyState === websock.CONNECTING) {

    // 若是 正在开启状态,则等待1s后重新调用

    setTimeout(function () {

      sendSock(agentData, callback,key)

    }, 2000)

  } else {

    // 若未开启 ,则等待1s后重新调用

    setTimeout(function () {

      sendSock(agentData, callback,key)

    }, 2000)

  }

}

function getSock(key,callback) {

  globalCallback.set(key,callback)

}

// 数据接收

function websocketonmessage(e) {

  let ret = JSON.parse(decodeUnicode(e.data))

  if (!ret) {

    heartCheck.reset()

  } else {

    if (ret.msg === "websocket connect success") { 

    } else {

      if (ret.method === "webSocket_device_transport"){

        const callback = globalCallback.get(ret.sn)

        if (callback && typeof callback === "function")

        callback(ret);

      }else if(ret.method === "webSocket_device_alarm"){ 

        const callback = globalCallback.get('deviceAlert')

        if (callback && typeof callback === "function")

        callback(ret);

      }

    }

  }

  // globalCallback(JSON.parse(e.data))

  function decodeUnicode(str) {

    str = str.replace(/\\/g, "%");

    //转换中文

    str = unescape(str);

    //将其他受影响的转换回原来

    str = str.replace(/%/g, "\\");

    //对网址的链接进行处理

    str = str.replace(/\\/g, "");

    return str;

  }

}

// 数据发送

function websocketsend(agentData) {

  console.log("数据发送",JSON.stringify(agentData))

  websock.send(JSON.stringify(agentData))

}

// 关闭

function websocketclose(e) {

  console.log(e)

  isConnect = false ; //断开后修改标识

  heartCheck.stop()

  console.log('connection closed (' + e.code + ')')

}

// 创建 websocket 连接

function websocketOpen(e) {

  isConnect = true

  console.log('连接成功')

}

//登录成功后再建立连接

//initWebSocket()

// 将方法暴露出去

export {

  sendSock,

  getSock,

  createWebSocket,

  closeWebSocket,

  initWebSocket

}

————————————————

版权声明:本文为CSDN博主「Hello 阿凡达」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_38746300/article/details/128675243

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
利用websoket+video+canvas实现简易的web视频功能
九种跨域方式实现原理
最简单的WebRTC示例
WebSocket的简单介绍及应用
js实现mp3录音通过websocket实时传送+简易波形图
细说WebSocket - Node篇
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服