微信小程序使用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;
        }
    },
相关推荐
行百里er2 小时前
WebSocket 在 Spring Boot 中的实战解析:实时通信的技术利器
spring boot·后端·websocket
小小王app小程序开发6 小时前
抽赏小程序特殊赏玩法开发全解析:技术实现+架构支撑+合规落地
小程序·架构
江南西肥肥7 小时前
从手绘图到小程序,我用AI花了2个小时完成
小程序·vibecoding·claudecode
Voyager_411 小时前
OS八股:HTTP 与 WebSocket 的通信模型差异 —— 理解等待、轮询、阻塞与全双工
websocket·网络协议·http
辰风沐阳12 小时前
JavaScript 的 WebSocket 使用指南
开发语言·javascript·websocket
柠檬树^-^13 小时前
小程序定位
小程序
计算机毕设指导613 小时前
基于微信小程序民宿预订管理系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
测试199814 小时前
用Postman测WebSocket接口
自动化测试·软件测试·python·websocket·测试工具·接口测试·postman
tjjucheng15 小时前
专业小程序定制开发公司推荐
大数据·小程序