小工具知识网

当前位置: 首页 > 行业知识 > uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一

行业知识

uni-app vue3 封装socket 兼容微信小程序 钉钉小程序 H5 App 全局唯一

2026-11-08 03:42:26 来源:互联网转载

文章目录

    • 概要
    • 初始化 创建连接
    • 接收事件
    • 示例
    • js代码
    • 自定义修改说明
    • 小���

      概要

      前端小伙伴使用uni-app开发长连接通信的时候都会有以下疑问

      ()
      • 在网上搜到的封装socket都没讲怎么全局公用一个呢?
      • 同一个 子协议或者我我们叫type类型型我想在两个页面都接受使用怎么做呢?

        目前能搜到的socket 封装好像都没讲清楚这个东西,或者压根没考虑

        下面给大家详细介绍下我封装的方法 大家拿去就可以用。代码在最后了

        ()

        初始化 创建连接

        • 在合适的场景下创建 Socket 连接
        • 初始化后所有页面均可使用
          import socket from "@/components/lvSocket.js"onLoad(()=>{ // 假设在onLoad周期需要初始化socket.connect();// 初始化 全局只需初始化一次})onUnload(()=>{socket.clearClose();// 关闭长连接根据需要使用})

          接收事件

          注意 type等于all时接收所有类型参数

          import socket from "@/components/lvSocket.js"onLoad(()=>{ // 假设在onLoad周期需要初始化// 发送消息socket.send({"type": "msgList",// 传输类型 "payLoad": {传输内容}});socket.on("hei",shjian);// type=hei:接受hei类型参数socket.on("hei",()=>{console.log('hei收到了')});// type=hei:接受hei类型参数socket.on("heier",()=>{console.log('er收到了')});// type=heier:接受hei类型参数socket.on("all",jieshouAll);// type=all:接受所有参数 all为type类型关键字})const shjian = (meg)=>{console.log('页面收到hei数据',meg)}const jieshouAll = (meg)=>{console.log('服务端返回的所有数据都能接收到',meg)}// 页面卸载清除事件回调onUnload(()=>{socket.off();// 清空所有回调socket.off('hei');// 清除某个类型所有回调socket.off('hei',jieshou);// 清除某个类型中某个回调})

          示例

          在两个页面 接受同一个类型 也是互不影响的。 清除的时候别误删了其他事件哦

          import socket from "@/components/lvSocket.js"// index 页面onLoad(()=>{socket.connect();// 初始化 全局只需初始化一次socket.on("hei",jieshou);// type=hei:接受hei类型参数socket.on("all",jieshouAll);// type=all:接受所有参数 all为type类型关键字})const jieshou = (meg)=>{console.log('页面收到数据',meg)socket.send({type:"pingaaaaa"});// 发送消息}const jieshouAll = (meg)=>{console.log('服务端返回的所有数据都能接收到',meg)}// 页面卸载清除事件回调onUnload(()=>{socket.off();// 清空所有回调socket.off('hei');// 清除某个类型所有回调socket.off('hei',jieshou);// 清除某个类型中某个回调socket.clearClose();// 关闭长连接根据需要使用})// home页面onLoad(()=>{socket.on("bookList",getBookList);// 接受参数})const getBookList = (meg)=>{console.log('页面收到数据',meg)}// 页面卸载清除事件回调onUnload(()=>{socket.off('bookList');// 清除某个类型所有回调})

          js代码

          在 src/components 路径下创建 lvSocket.js 粘贴如下代码到文件中

          vue2使用请注意this指向问题

          /*假设后端响应数据类型是这样的{ type:'msglist',"payload":{... 数据在这里}}*//**** @description: WebSocket 单例模式* @author: lvhao*/class Socket {constructor() {this.socket = null;// socket实例this.isConnect = false;// 是否连接成功this.reconnectCount = 0;// 重连接次数this.reconnectTimer = null;// 重连定时器this.url = `ws://192.168.28.38:3000`this.isHandClose = false;// 是否是手动关闭// 心跳定时器this.heartbeatInterval = null;// 收集事件绑定类型this._map = new Map();// 收集未连接成功要发送的消息this._sendArr = [];}// 连接connect() {if (this.socket) return;// 正在连接const Token = uni.getStorageSync('Token');this.socket = uni.connectSocket({url:this.url,header: {"wsToken": `Bearer ${Token}`,},complete: ()=> {},multiple:true,})// 连接成功this.socket.onOpen(()=>{console.log("连接成功")this._onOpen();})// Socket 连接关闭事件this.socket.onClose(() => {console.log("连接关闭了")this._onClose();});// 监听 Socket 错误事件this.socket.onError((err) => {console.log("Socket报错了",err)this._onError();});// 监听 WebSocket 接受到服务器的消息事件this.socket.onMessage((meg)=>{this._onMessage(meg)});}// 连接成功 重置参数_onOpen() {this.isConnect = true;// 是否连接成功this.reconnectCount = 0;// 重置重连次数clearTimeout(this.reconnectTimer);// 清空重连定时器this.isHandClose = false;// 是否是手动关闭this._heartbeat();// 开启心跳// 未发送的消息全部发送this._sendArr.forEach(item=>{this.send(item);// 发送消息})this._sendArr = [];}// 监听 WebSocket 连接关闭事件_onClose() {this.socket = null;// 清空soketthis.isConnect = false;// 是否连接成功this._clearHeartbeat();// 关闭心跳this._reconnect();// 重新连接}// 监听 WebSocket 错误事件_onError() {}// 监听 WebSocket 接受到服务器的消息事件_onMessage(meg) {let data = JSON.parse(meg.data);// 收到的数据let receiveType = data.type;// 收到的type类型// 触发对应type类型事件  接受type为all时所有事件都会触发for (let entry of this._map.entries()) {if(entry[1] === receiveType || entry[1] === 'all' ){entry[0](data.payLoad)}}}// 自动重连_reconnect() {if(this.isHandClose)return;// 手动关闭不重连if(this.socket)return;// 正在连接不处理if (this.reconnectCount  {console.log(`WebSocket 重连中,第 ${this.reconnectCount} 次尝试...`);this.connect();//连接}, 5000);} else {console.log('WebSocket 重连失败!');}}// 开启心跳_heartbeat(){this._clearHeartbeat();// 关闭心跳// 心跳10000ms发送一次this.heartbeatInterval = setInterval(()=>{this.send({type:'ping', "payLoad": {"ts": new Date().getTime()}})//心跳内容},10000)}// 关闭心跳_clearHeartbeat(){clearInterval(this.heartbeatInterval)}// 发送消息send(data) {// 当前未连接记录内容 队列中没有才放入 心跳除外if(!this.isConnect && data.type !== "ping" ){const hasEqualItem = this._sendArr.some(item => JSON.stringify(item) == JSON.stringify(data));if (!hasEqualItem) {this._sendArr.push(data);}return;}this.socket.send({'data':JSON.stringify(data)});}// 接受信息  type 类型  fn 回调函数on(type,fn=()=>{}){this._map.set(fn,type);}// 关闭接受参数off(type,fn){// 关闭参数if(arguments.length === 0){// 清除全部this._map.clear();}else if(arguments.length === 1){// 清除某个事件类型整体this._map.forEach((value, key) => {if (value === type) {this._map.delete(key);}});}else{// 清除某个事件类型中某个回调if(this._map.get(fn) === type){this._map.delete(fn)}}}// 关闭clearClose() {this.isHandClose = true;// 手动关闭clearTimeout(this.reconnectTimer);// 清空重连定时器if(this.socket && "close" in this.socket){this.socket.close(); // 关闭soket}}}export default new Socket()

          自定义修改说明

          • 后端参数
            代码开头有提到默认后端给到的数据为{ type:'msglist',// 你和后端定义的数据type类型"data":{"key":"value",// 这个type类型对应的数据...}}如果数据有修改。修改_onMessage函数修改传入你们定义的数据即可
          • 心跳
            修改代码中_heartbeat函数 修改心跳内容和心跳间隔时间即可
          • 重连
            默认最多重连10次  10次都失败就不会重新连接了默认重连间隔时间5秒只有连接失败 或者服务报错才会重新连接  我们手动关闭连接是不会重新连接的放心使用修改_reconnect函数中的10 为你想要的重连次数修改_reconnect函数中的5000 为你想要的重连间隔时间

            小结

            可以根据自己的需要对其进行魔改。 不懂的地方可以联系我帮大家答疑。v:H1274714546

            欢迎有更好方案的小伙伴评论。分享转载,请注明来源哦~

上一篇:【Spring Boot】掌握Spring Boot:深入解析配置文件的使用与管理

下一篇:怎么制作大型网站地图?