微信小程序使用websocket

全局监听,单页页面使用监听数据

app.js页面代码

javascript 复制代码
const { webSocketUrl } = require('./http/env').prod;
App({

    globalData: { 
         // ===== WebSocket 全局配置 =====
        wsUrl: '', // 替换为实际的WebSocket服务地址
        wsConn: null, // WebSocket连接实例
        wsStatus: false, // 连接状态:false-未连接 true-已连接
        // wsMsgList: [], // 存储所有收到的WS消息
        wsReconnectTimer: null, // 重连定时器
        wsReconnectInterval: 3000, // 重连间隔(毫秒)
        wsMessageListeners: [], // 页面消息监听回调列表
    },
    onLaunch() {  
        // 检查登录状态
        this.checkLoginStatus(); 
        // 初始化系统信息
        this.initSystemInfo();
        let tenantId = wx.getStorageSync('TENANT-ID')
        let studentId = wx.getStorageSync('userInfo').username 
        let wsUrl = `wss://${webSocketUrl}/admin/ws/messages?tenantId=${tenantId}&studentId=${studentId}`//替换成自己的后端地址就行
        this.globalData.wsUrl =  wsUrl
        console.log(wsUrl,'wsUrl');
        const token = wx.getStorageSync('access_token');
        if (token) {
            this.initWebSocket();
        }
    },
    initWebSocket() {
        const that = this;
        // 清空旧定时器
        if (that.globalData.wsReconnectTimer) {
            clearTimeout(that.globalData.wsReconnectTimer);
            that.globalData.wsReconnectTimer = null;
        }

        // 关闭旧连接
        if (that.globalData.wsConn) {
            that.globalData.wsConn.close();
            that.globalData.wsConn = null;
        }

        // 创建新连接
        const access_token = wx.getStorageSync('access_token');
        const wsTask = wx.connectSocket({
            url: that.globalData.wsUrl,
            header: {
                // 可添加认证信息,比如token
                'Authorization': `Bearer ${access_token}`,  // 添加认证头
                'CLIENT-TOC':'Y'
            }, 
            success: () => {
                console.log('WS: 连接请求发送成功');
            },
            fail: (err) => {
                console.error('WS: 连接请求失败', err);
                that.globalData.wsStatus = false;
                // 触发重连
                that.reconnectWebSocket();
            }
        });

        // 保存连接实例
        that.globalData.wsConn = wsTask;

        // 监听连接打开
        wsTask.onOpen(() => {
            console.log('WS: 连接成功');
            that.globalData.wsStatus = true;
            // 连接成功后清空重连定时器
            if (that.globalData.wsReconnectTimer) {
                clearTimeout(that.globalData.wsReconnectTimer);
                that.globalData.wsReconnectTimer = null;
            }
        });

        // 监听消息接收
        wsTask.onMessage((res) => {
            console.log('WS: 收到消息', res);
            try {
                // 解析消息(根据实际服务端格式调整)JSON.parse
                const msg = (res.data);
                // 存储消息到全局
                // that.globalData.wsMsgList.push(msg);
                // 触发所有页面监听回调
                that.globalData.wsMessageListeners.forEach(cb => {
                    cb(msg);
                });
            } catch (e) {
                console.error('WS: 消息解析失败', e);
            }
        });

        // 监听连接关闭
        wsTask.onClose((res) => {
            console.log('WS: 连接关闭', res);
            that.globalData.wsStatus = false;
            that.globalData.wsConn = null;
            // 非主动关闭则重连(小程序未退出时)
            if (!res.code || res.code !== 1000) {
                that.reconnectWebSocket();
            }
        });

        // 监听连接错误
        wsTask.onError((err) => {
            console.error('WS: 连接错误', err);
            that.globalData.wsStatus = false;
            // 触发重连
            that.reconnectWebSocket();
        });
    },

    /**
     * WebSocket重连机制
     */
    reconnectWebSocket() {
        const that = this;
        // 避免重复重连
        if (that.globalData.wsReconnectTimer) return;
        
        console.log(`WS: ${that.globalData.wsReconnectInterval}ms后尝试重连`);
        that.globalData.wsReconnectTimer = setTimeout(() => {
            that.initWebSocket();
        }, that.globalData.wsReconnectInterval);
    },

    /**
     * 页面订阅WebSocket消息
     * @param {Function} callback 消息回调函数
     * @returns {Function} 取消订阅的方法
     */
    subscribeWsMessage(callback) {
        const that = this;
        // 添加回调到监听列表
        that.globalData.wsMessageListeners.push(callback);
        // 返回取消订阅方法
        return () => {
            const index = that.globalData.wsMessageListeners.findIndex(cb => cb === callback);
            if (index > -1) {
                that.globalData.wsMessageListeners.splice(index, 1);
            }
        };
    },

    /**
     * 主动发送WebSocket消息
     * @param {Object/string} data 要发送的消息
     * @returns {Promise} 发送结果
     */
    sendWsMessage(data) {
        const that = this;
        return new Promise((resolve, reject) => {
            if (!that.globalData.wsStatus || !that.globalData.wsConn) {
                reject(new Error('WS: 连接未建立'));
                return;
            }

            const sendData = typeof data === 'object' ? JSON.stringify(data) : data;
            that.globalData.wsConn.send({
                data: sendData,
                success: () => resolve(true),
                fail: (err) => reject(err)
            });
        });
    },

    /**
     * 主动关闭WebSocket连接(一般不需要,小程序退出时自动关闭)
     */
    closeWebSocket() {
        const that = this;
        if (that.globalData.wsConn) {
            // 主动关闭时传入1000状态码(正常关闭),避免重连
            that.globalData.wsConn.close({ code: 1000, reason: '主动关闭' });
            that.globalData.wsConn = null;
            that.globalData.wsStatus = false;
        }
        // 清空重连定时器
        if (that.globalData.wsReconnectTimer) {
            clearTimeout(that.globalData.wsReconnectTimer);
            that.globalData.wsReconnectTimer = null;
        }
    },


    onShow() {
        // 小程序切回前台,检查WS连接状态,断开则重连
        const that = this;
        if (!that.globalData.wsStatus && !that.globalData.wsReconnectTimer) {
            // const token = wx.getStorageSync('access_token');
            // if (token) {
                this.reconnectWebSocket();
            // } 
        }
    },

    onUnlaunch() {
        console.log('小程序关闭,关闭WS连接');
        this.closeWebSocket();
        // 清空消息监听列表
        this.globalData.wsMessageListeners = [];
    },

})

页面使用的代码

javascript 复制代码
onLoad() {
     
        this.unsubscribeWs = getApp().subscribeWsMessage((msg) => {
            console.log('页面收到WS消息', msg); 
            //获取监听消息进行处理
        });
    },
//清除监听
 onUnload() { 
        if (this.unsubscribeWs) {
            this.unsubscribeWs();
            this.unsubscribeWs = null;
        }
    },
相关推荐
发财北1 小时前
线上交友APP怎么开发?
小程序
2501_915921431 小时前
Bundle Id 创建与管理的工程化方法,一次团队多项目协作中的流程重构
服务器·ios·小程序·重构·https·uni-app·iphone
少云清2 小时前
【功能测试】4_小程序项目 _Ego微商小程序测试点分析
功能测试·小程序
是店小二呀2 小时前
本地 Websocket 调试总碰壁?cpolar一招让远程访问变简单
网络·websocket·网络协议
说私域3 小时前
直播带货的困境与突破:基于“开源AI智能名片链动2+1模式S2B2C商城小程序”的创新研究
人工智能·小程序·开源
2501_915909063 小时前
深度解析 iOS 内存占用,构建多工具协同的内存诊断、监控与优化体系
android·ios·小程序·https·uni-app·iphone·webview
菜鸟学Python4 小时前
零基础用AI编程开发微信小程序-开始篇
微信小程序·小程序·ai编程
q_19132846954 小时前
基于Springboot2+Vue2+uniapp的单商家在线点餐外卖小程序
vue.js·spring boot·mysql·小程序·uni-app·计算机毕业设计
2501_915918415 小时前
iOS CPU 使用率深度分析,多工具协同定位高占用瓶颈的工程化方法
android·ios·小程序·https·uni-app·iphone·webview