在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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/27096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML 区块

HTML 区块 HTML&#xff08;超文本标记语言&#xff09;是构建网页的标准语言&#xff0c;它定义了网页的结构和内容。在HTML中&#xff0c;区块元素是用来组织页面内容的重要工具。这些元素通常用于创建如段落、列表、头部、底部、导航栏等较大的内容块。本文将详细介绍HTML中…

JavaScript 错误解析与最佳实践:隐式返回对象字面量的正确写法

在JavaScript开发中&#xff0c;箭头函数&#xff08;Arrow Functions&#xff09;因其简洁的语法和灵活的功能而广受欢迎。然而&#xff0c;在使用箭头函数返回对象字面量时&#xff0c;开发者常常会遇到一些语法错误。本文将通过一个常见的错误示例&#xff0c;详细解析其原因…

网络安全攻防演练:提升应急响应能力

网络安全攻防演练&#xff1a;提升应急响应能力 在网络攻击日益频繁和复杂的今天&#xff0c;网络安全攻防演练成为提升组织应急响应能力的重要手段。通过模拟真实攻击场景&#xff0c;攻防演练能够帮助组织检验和提高其网络安全防护和应急处理能力。 一、网络安全攻防演练的…

探索微软Edge:新时代的浏览器先锋

随着互联网的快速发展&#xff0c;浏览器在我们日常生活中扮演着越来越重要的角色。微软Edge作为一款现代化的浏览器&#xff0c;以其独特的功能和优越的性能吸引了大量用户。本文将深入探索微软Edge&#xff0c;揭示其亮点和优势&#xff0c;帮助你更好地了解和使用这款浏览器…

【Tomcat】日志相关设置

Tomcat的日志文件设置涉及到多个方面&#xff0c;包括日志文件的存放位置、日志类型、日志级别以及日志的滚动和分割等。以下是一个清晰的Tomcat日志文件设置指南&#xff0c;参考了上述文章中的信息&#xff1a; 1. 日志文件存放位置 Tomcat的日志文件通常存放在Tomcat安装目…

前端必看的2024 年 7 个 Web 前端开发趋势【文末福利=网盘分享2024web前端技术资料,学习资源】

目录 前言 趋势一&#xff1a;新的样式解决方案和组件库将持续涌现 趋势二&#xff1a;利用 AI 来增强开发流程 趋势三&#xff1a;SSR 和 SSG 两种框架之间的竞争将会愈演愈烈 趋势四&#xff1a;前端、后端和全栈开发之间的界限将越来越模糊 趋势五&#xff1a;越来越多的人…

Python数据库编程指南:连接与操作SQLite与MySQL

目录 一、引言 二、SQLite数据库连接与操作 &#xff08;一&#xff09;安装SQLite库 &#xff08;二&#xff09;建立数据库连接 &#xff08;三&#xff09;执行SQL语句 &#xff08;四&#xff09;注意事项 三、MySQL数据库连接与操作 &#xff08;一&#xff09;安…

阿里云 Ubuntu 22.04.4 LTS 安装postfix+dovecot 搭建邮件服务器

一 安装 1安装postfix sudo apt-get install postfix #如果没有弹出配置界面&#xff0c;运行 dpkg-reconfigure postfix #sudo vim /etc/postfix/main.cf smtpd_banner $myhostname ESMTP $mail_name (Ubuntu) biff no append_dot_mydomain no readme_directory no co…

Leetcode.2786 访问数组中的位置使分数最大

题目链接 Leetcode.2786 访问数组中的位置使分数最大 rating : 1732 题目描述 给你一个下标从 0 0 0 开始的整数数组 n u m s nums nums 和一个正整数 x x x 。 你 一开始 在数组的位置 0 0 0 处&#xff0c;你可以按照下述规则访问数组中的其他位置&#xff1a; 如果你…

阿里云 OpenSearch RAG 应用实践

2024年5月18日&#xff0c;阿里巴巴 OpenSearch 研发负责人刑少敏应邀参与AICon全球人工智能开发与应用大会暨大模型应用生态展&#xff0c;分享《OpenSearch RAG 应用实践》&#xff0c;介绍了阿里云OpenSearch在RAG方面的应用和探索。以下是主题演讲的逐字稿分享&#xff1a;…

Python学习之旅:你的大学计算机专业宝藏路线图

在信息时代的浪潮中&#xff0c;Python以其强大的功能和极简的语法成为了无数程序员心中的白月光。作为大学计算机专业的学生&#xff0c;掌握Python不仅能够为未来的职业生涯铺路&#xff0c;更能让您在学术研究和实际应用中如鱼得水。今天&#xff0c;我将与大家分享一套实用…

【SQL边干边学系列】08高级问题-4

文章目录 前言回顾高级问题48.客户分组49.客户分组-修复null50.使用百分比的客户分组51.灵活的客户分组 答案48.客户分组49.客户分组-修复null50.使用百分比的客户分组51.灵活的客户分组 未完待续 前言 该系列教程&#xff0c;将会从实际问题出发&#xff0c;边干边学&#xff…

LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

文章汇总 总体来看像是一种带权重的残差&#xff0c;但解决的如何高效问题的事情。 相比模型的全微调&#xff0c;作者提出固定预训练模型参数不变&#xff0c;在原本权重矩阵旁路添加低秩矩阵的乘积作为可训练参数&#xff0c;用以模拟参数的变化量。 模型架构 h W 0 x △…

游戏开发求职面试宝典:如何做好面试准备

面试的时候&#xff0c;你是否也遇到or担心会面临如下的问题: “哎,今天的面试又没有拿到offer”。 ”面试了好多回了&#xff0c;还是没有好的offer,算了随便找个工作先干着吧”。 “今年的市场行情真不行啊&#xff0c;早知道就不离职了”。 …… 出现以上的情况&#x…

趣谈网络协议

趣谈网络协议 原文链接:https://time.geekbang.org/column/intro/100020901?tabcatalog 第3讲 | ifconfig&#xff1a;最熟悉又陌生的命令行如何理解 ip addr &#xff1f;如果理解32位IP地址的5个分类&#xff1f;如何理解A&#xff0c;B&#xff0c;C三类地址的最大主机数和…

Mybatis和Hibernate的作用区别及底层原理分析

目录 Mybatis的作用及底层原理 Hibernate的作用及底层原理 Mybatis与Hibernate的主要区别 Mybatis和Hibernate都是Java应用程序中常用的ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;框架&#xff0c;它们的主要作用是简化数据库访问层的开…

XXE漏洞详解:从基础到防御

引言 在网络安全领域&#xff0c;XXE&#xff08;XML External Entity&#xff09;漏洞是一种常见的安全风险&#xff0c;它允许攻击者通过XML文档读取服务器上的文件&#xff0c;甚至执行远程服务器请求。本文将深入探讨XXE漏洞的基本概念、攻击手段以及如何有效防御。 XXE漏…

31、shell循环

一、循环 循环&#xff1a;循环是一种重复执行一段代码的结构。只要满足循环的条件&#xff0c;会一直执行这个代码。 循环条件&#xff1a;在一定范围之内&#xff0c;按照指定的次数来执行循环。 循环体&#xff1a;在指定的次数内&#xff0c;执行的命令序列。只要条件满…

深入解析 Spring Cloud Seata:分布式事务的全面指南

&#x1f9e8;&#x1f9e8;&#x1f9e8;深入解析 Spring Cloud Seata&#xff1a;分布式事务的全面指南 在微服务架构中&#xff0c;分布式事务的处理是一项复杂而重要的任务。Spring Cloud Seata 是一款专为分布式事务而设计的解决方案&#xff0c;它由阿里巴巴开源&#x…

记录一次网络延迟的事件分析

场景&#xff1a;几天前&#xff0c;某资源池的服务器ping 延迟500ms以上&#xff0c;感觉网络有问题&#xff0c;同时查看服务器的负载&#xff0c;发现不高&#xff0c;带宽也没有超限。 排查经过&#xff1a;仔细分析&#xff0c;查看日志&#xff0c;发现是一些延迟的信息…