微信小程序使用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;
        }
    },
相关推荐
00后程序员张1 天前
python 抓包在实际项目中的合理位置,结合代理抓包、设备侧抓包与数据流分析
android·ios·小程序·https·uni-app·iphone·webview
2501_915918411 天前
使用 HBuilder 上架 iOS 应用时常见的问题与应对方式
android·ios·小程序·https·uni-app·iphone·webview
2501_916007471 天前
iOS 崩溃日志的分析方法,将崩溃日志与运行过程结合分析
android·ios·小程序·https·uni-app·iphone·webview
2501_916007471 天前
React Native 混淆在真项目中的方式,当 JS 和原生同时暴露
javascript·react native·react.js·ios·小程序·uni-app·iphone
00后程序员张1 天前
苹果应用商店上架App流程,签名证书、IPA 校验、上传
android·ios·小程序·https·uni-app·iphone·webview
2501_916007471 天前
iOS 上架需要哪些准备,围绕证书、描述文件和上传方式等关键环节展开分析
android·ios·小程序·https·uni-app·iphone·webview
qq_12498707531 天前
基于微信小程序的私房菜定制上门服务系统(源码+论文+部署+安装)
java·spring boot·微信小程序·小程序·毕业设计·毕设
2501_915106321 天前
iOS 上架费用解析,哪些成本可以通过流程优化降低。
android·ios·小程序·https·uni-app·iphone·webview
换日线°1 天前
微信小程序找不同游戏(有效果图)
游戏·微信小程序
风月歌2 天前
小程序项目之超市售货管理平台小程序源代码(源码+文档)
java·微信小程序·小程序·毕业设计·源码