当前位置: 首页 > news >正文

在vue和uniapp中使用 websocket并封装js

vue中

websocket.js 

import store from '@/store'
import { Message } from 'element-ui'
var ws;
var tt;
var lockReconnect = false;//避免重复连接
var clientId = localStorage.getItem("clientId")//缓存中取出客户端idvar websocket = {Init: function (url, clientId) {if ("WebSocket" in window) {ws = new WebSocket(url + clientId);} else if ("MozWebSocket" in window) {ws = new MozWebSocket(url + clientId);} else {console.log("您的浏览器不支持 WebSocket!");return;}ws.onmessage = function (e) {console.log("接收消息:" + e.data)heartCheck.start()if (e.data == 'ok') {//心跳消息不做处理return}//messageHandle(e.data)}ws.onclose = function () {console.log("连接已关闭")Message({message: '连接已关闭',type: 'error',});reconnect(clientId);}ws.onopen = function () {console.log("连接成功")Message({message: '连接成功',type: 'success',});heartCheck.start();}ws.onerror = function (e) {console.log("数据传输发生错误");Message({message: '数据传输发生错误',type: 'error',});reconnect(clientId)}},Send: function (sender, reception, body, flag) {let data = {sender: sender,reception: reception,body: body,flag: flag}let msg = JSON.stringify(data)console.log("发送消息:" + msg)ws.send(msg)},getWebSocket() {return ws;},getStatus() {if (ws.readyState == 0) {return "未连接";} else if (ws.readyState == 1) {return "已连接";} else if (ws.readyState == 2) {return "连接正在关闭";} else if (ws.readyState == 3) {return "连接已关闭";}}
}export default websocket;//根据消息标识做不同的处理
function messageHandle(message) {let msg = JSON.parse(message)switch (msg.flag) {case 'command':console.log("指令消息类型")break;case 'inform':console.log("通知")break;default:console.log("未知消息类型")}
}function reconnect(sname) {if (lockReconnect) {return;};lockReconnect = true;//没连接上会一直重连,设置延迟避免请求过多tt && clearTimeout(tt);tt = setTimeout(function () {console.log("执行断线重连...")websocket.Init(sname);lockReconnect = false;}, 4000);
}//心跳检测
var heartCheck = {timeout: 1000 * 60 * 3,timeoutObj: null,serverTimeoutObj: null,start: function () {console.log('开始心跳检测');var self = this;this.timeoutObj && clearTimeout(this.timeoutObj);this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);this.timeoutObj = setTimeout(function () {//这里发送一个心跳,后端收到后,返回一个心跳消息,//onmessage拿到返回的心跳就说明连接正常console.log('心跳检测...');ws.send("HeartBeat:" + clientId);self.serverTimeoutObj = setTimeout(function () {if (ws.readyState != 1) {ws.close();}// createWebSocket();}, self.timeout);}, this.timeout)}
}

使用方法

直接在生命周期里调用这个方法就可以,如果想在全局调用就在app.vue中使用

<template><div id="app"><router-view /></div>
</template><script>
import websocket from '@/js/websocket'
export default {name: 'App',created(){localStorage.setItem("clientId","user-1")websocket.Init("url地址","user-1")}
}
</script>

在uniapp中使用

websocket.js

let isSocketClose=false;    // 是否关闭socket
let reconnectCount=5;    // 重连次数
let heartbeatInterval="";   // 心跳定时器
let socketTask = null;  // websocket对象let  againTimer = null;//断线重连定时器let url = null;
let onReFn = null;
let onSucFn = null;
let onErrFn = null;/*** sockeUrl:websocet的地址* onReceive:消息监听的回调* onErrorEvent:抛出错误的回调,且弹窗连接失败的提示框* onErrorSucceed:抛出成功回调,主要用于隐藏连接失败的提示框* */
const sokcet= (sockeUrl,onReceive,onErrorEvent,onErrorSucceed)=> {url = sockeUrl;onReFn= onReceive;onErrFn= onErrorEvent;onSucFn= onErrorSucceed;isSocketClose=false; //判断是否有websocet对象,有的话清空if(socketTask){socketTask.close();socketTask = null;clearInterval(heartbeatInterval);}//WebSocket的地址// 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】let url = sockeUrl// 连接socketTask = uni.connectSocket({url: url,success(data) {console.log("websocket连接成功");clearInterval(againTimer)//断线重连定时器},fail: (err) => {console.log("报错",err);}});// 连接打开socketTask.onOpen((res)=>{console.log('WebSocket打开');clearInterval(againTimer)//断线重连定时器onErrorSucceed({isShow:false}) // 用于提示框的隐藏heartbeatInterval && clearInterval(heartbeatInterval);// 10秒发送一次心跳heartbeatInterval = setInterval(() => {sendMsg('心跳ing')}, 1000*5)})// 监听连接失败socketTask.onError((err)=>{console.log('WebSocket连接打开失败,请检查',err);//停止发送心跳clearInterval(heartbeatInterval)//如果不是人为关闭的话,进行重连if (!isSocketClose) { reconnect(url,onErrorEvent)}})// // 监听连接关闭 -socketTask.onClose((e) => {console.log('WebSocket连接关闭!');clearInterval(heartbeatInterval)if (!isSocketClose) {reconnect(url,onErrorEvent)}})// 监听收到信息socketTask.onMessage((res) => {uni.hideLoading()console.log(res,'res监听收到信息')let serverData = res.data//与后端规定好返回值分别代表什么,写业务逻辑serverData && onReceive(serverData);});}const reconnect = (url,onErrorEvent)=>{console.log('进入断线重连',isSocketClose);clearInterval(againTimer)//断线重连定时器clearInterval(heartbeatInterval);socketTask && socketTask.close(); // 确保已经关闭后再重新打开socketTask = null;onErrorEvent({isShow:true,messge:'扫描头服务正在连接...'})// 连接  重新调用创建websocet方法againTimer    = setInterval(()=>{sokcet(url,onReFn,onErrFn,onSucFn)console.log('在重新连接中...');},1000*5)}    const sendMsg = (msg)=>{   //向后端发送命令msg = JSON.stringify(msg)try{//通过 WebSocket 连接发送数据socketTask.send({data: msg});}catch(e){if(isSocketClose){return}else{reconnect(url,onErrFn)}}}
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}const stop = ()=>{isSocketClose = trueclearInterval(heartbeatInterval);clearInterval(againTimer)//断线重连定时器socketTask.close(); // 确保已经关闭后再重新打开socketTask = null;
}export const websocketObj = {sokcet,stop,sendMsg};

使用方法

<template><view class="container">{{ webtext }}</view>
</template>
<script>import { websocketObj } from '@/utils/websocket.js';export default {
data() {return {webtext:'',}
},methods: {//websocet函数回调:返回监听的数据getWebsocetData(val){// val = String.fromCharCode.apply(null, new Uint8Array(val)).trim()  如果后端返回数据格式是其他的,可能需要转换一下,比如这个,应该是转Unicode编码console.log(val,'函数回调');this.scanCode = val;},//websocet函数抛错: 返回错误信息 用于用户提示getWebsocetError(err){this.webtext = err.messge;console.log('websocet函数抛错');},//websocet函数成功进入: 监听连接状态,在失败的时候弹窗提示,具体需求看自身情况onErrorSucceed(val){console.log('websocet函数成功进入');}   },mounted() {},onLoad() {// 在onload的时候调用,创建webscoet连接对象,参数分别为:url、获取后端返回数据、监听websocket的链接失败返回的报错、监听链接状态,返回布尔值websocketObj.sokcet('ws://192.168.xxxx',this.getWebsocetData,this.getWebsocetError,this.onErrorSucceed)},//离开页面销毁websocketbeforeDestroy() {websocketObj.stop();},}
</script>

相关文章:

  • Android GLES渲染——渲染回读
  • MFC序列号输入框
  • 一套轻量、安全的问卷系统基座,提供面向个人和企业的一站式产品级解决方案
  • K-Means 算法详解
  • 游戏中的寻路算法研究
  • 解决内核模块加载使用-f参数无法加载的问题
  • 为什么要学Java?
  • Linux驱动开发(二)--字符设备驱动开发提升 LED驱动开发实验
  • 18个机器学习核心算法模型总结
  • 2025计算机毕业设计选题题目推荐-毕设题目汇总大全
  • 智慧校园综合管理系统:打造高效智慧的学校管理平台
  • 契约锁电子签章平台 add 远程命令执行漏洞复现(XVE-2023-23720)
  • 关于面试被面试官暴怼:“几年研究生白读” 的前因后果
  • React获取DOM节点
  • 【Android】基于webView打造富文本编辑器(H5)
  • 【node学习】协程
  • Angular 4.x 动态创建组件
  • Angular4 模板式表单用法以及验证
  • CAP 一致性协议及应用解析
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • echarts花样作死的坑
  • gf框架之分页模块(五) - 自定义分页
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • JS数组方法汇总
  • JS字符串转数字方法总结
  • leetcode386. Lexicographical Numbers
  • node 版本过低
  • PAT A1050
  • session共享问题解决方案
  • socket.io+express实现聊天室的思考(三)
  • SpiderData 2019年2月23日 DApp数据排行榜
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 学习笔记TF060:图像语音结合,看图说话
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ​iOS实时查看App运行日志
  • ​Java并发新构件之Exchanger
  • ​插件化DPI在商用WIFI中的价值
  • !!java web学习笔记(一到五)
  • # 再次尝试 连接失败_无线WiFi无法连接到网络怎么办【解决方法】
  • #Datawhale X 李宏毅苹果书 AI夏令营#3.13.2局部极小值与鞍点批量和动量
  • #laravel 通过手动安装依赖PHPExcel#
  • (补)B+树一些思想
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .env.development、.env.production、.env.staging
  • .equals()到底是什么意思?
  • .gitignore文件使用