webSocket通信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']));

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

属性值属性常量描述
0CONNECTING正在与服务端建立WebSocket连接,还没有连接成功
1OPEN连接成功并打开,可以发送消息
2CLOSING进行关闭连接的操作,且尚未关闭
3CLOSE连接已关闭或不能打开

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

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

②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连接关闭时触发,只触发一次
  1. 使用示例
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中

  1. 直接引用文件 方法 调用

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
}

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值