UniApp对接WebSocket实现实时通信与页面刷新

发布于:2025-03-07 ⋅ 阅读:(107) ⋅ 点赞:(0)

本文将详细介绍如何在UniApp项目中对接WebSocket进行实时通信,并使用Vuex管理WebSocket消息的状态。通过封装uni原生的WebSocket API,创建一个工具类`websocket.js`,并在应用启动时初始化WebSocket连接,确保能够实时监听和更新页面。

1. 封装uni原生的WebSocket,写出工具类`websocket.js`
2. 下载Vuex,并在`main.js`中添加Vuex store,并在应用实例化时初始化WebSocket连接

1、封装uni原生的WebSocket

首先,我们需要封装uni原生的WebSocket API,以便在项目中方便地使用WebSocket功能。我们将创建一个工具类`websocket.js`来管理WebSocket实例及其相关方法。

// websocket.js
// 基础消息模板
const socketMessageTemplate = {
    type: "", // 消息类型
    timestamp: null, // 时间戳
    data: null, // 数据
    from: "", // 发送者
    to: "", // 接收者
    msg: "", // 消息内容
};
 
// WebSocket 管理类
class WebSocketManager {
    constructor({
        // 最大重连次数
        maxReconnectAttempts = 6,
        // 重连间隔(毫秒)
        reconnectInterval = 60000,
        // 心跳间隔(毫秒)
        heartbeatInterval = 60000,
    } = {}) {
        this.socket = null; // WebSocket 实例
        this.listeners = {}; // 事件监听器
        this.status = "closed"; // 连接状态:closed, connecting, connected
        this.heartbeatTimer = null; // 心跳定时器
        this.reconnectAttempts = 0; // 当前重连次数
        this.maxReconnectAttempts = maxReconnectAttempts; // 最大重连次数
        this.reconnectInterval = reconnectInterval; // 重连间隔(毫秒)
        this.heartbeatInterval = heartbeatInterval; // 心跳间隔(毫秒)
        this.url = null; // WebSocket 地址
        this.isManualClose = false; // 是否为用户主动关闭
    }
 
    /**
     * 连接 WebSocket
     * @param {string} url WebSocket 地址
     * @param {function} successCallback 连接成功回调函数
     */
    connect(url, successCallback = () => { }) {
        if (!url) {
            console.error("WebSocket 地址不能为空");
            return;
        }
        /* if (this.status === "connecting") {
            console.warn("WebSocket 正在连接中,请稍后再试");
            return;
        } */
        if (this.status === "connected") {
            console.warn("WebSocket 已连接,请勿重复连接");
            return;
        }
 
        this.url = url;
        this.status = "connecting";
        this.isManualClose = false; // 重置手动关闭标志
        this.socket = uni.connectSocket({
            url,
            success: () => {
                successCallback();
                console.log("WebSocket 连接请求已发送");
            },
            fail: (error) => {
                console.error("WebSocket 连接失败", error);
                this.status = "closed";
                this.handleReconnect();
            },
        });
        this.initEventHandlers();
    }
 
    /**
     * 初始化 WebSocket 事件
     */
    initEventHandlers() {
        uni.onSocketOpen(() => {
            if (this.status === "connected") return; // 避免重复发送初始化消息
            this.status = "connected";
            this.reconnectAttempts = 0;
            this.startHeartbeat();
            this.triggerEvent("open");
        });
 
        uni.onSocketMessage(({ data }) => { 
            try {
				    console.log("消息解析111", data);
                // const message = JSON.parse(decodeURIComponent(data));
				   const message = JSON.parse(data);
				     console.log("消息解析websoket22222222", message);
				    store.commit('ADD_MESSAGE',message.category);
            } catch (err) {
                // console.error("消息解析失败", err);
            }
        });
 
        uni.onSocketError((err) => {
            console.error("WebSocket 错误", err);
            this.triggerEvent("error", err);
        });
 
        uni.onSocketClose(() => {
            this.status = "closed";
            this.stopHeartbeat();
            this.triggerEvent("close");
            if (!this.isManualClose) {
                this.handleReconnect();
            }
        });
    }
 
    /**
     * 处理重连逻辑
     */
    handleReconnect() {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试第 ${this.reconnectAttempts} 次重连...`);
            this.status = "connecting";
            setTimeout(() => this.connect(this.url), this.reconnectInterval);
        } else {
            this.status = "fail";
            console.error("重连次数已达上限,停止重连");
        }
    }
 
    /**
     * 启动心跳机制
     */
    startHeartbeat() {
        this.stopHeartbeat(); // 避免重复启动
        this.heartbeatTimer = setInterval(() => {
            if (this.status ==

网站公告

今日签到

点亮在社区的每一天
去签到