uniapp使用WebSocket断线,心跳重连机制

项目场景:

提示:我们在使用WebSocket,经常会遇到有的时候给别人发消息,别人会接收不到,这个时候就有可能是WebSocket断线了,所以这个时候心跳包就出现了


解决方案:

提示:可直接使用,记得把对应地址替换一下


const RECONNECT_INTERVAL = 3000; // 延迟3秒后进行重连
const HEARTBEAT_INTERVAL = 20000; // 每20秒发送一次心跳消息

export default {
    data () {
        return {
            isOpen: false, // WebSocket是否打开
            clientId: null, // 用户ID
            socketTimer: null, // 定时器
        }
    },
    methods: {
        // 发送心跳包
        startHeartbeat () {

            // HeartBeat 这里是和后端约定好的值,我们发送给后端,后端再把这个值返给我们
            // 目的就是让后端知道我们一直在
            const heartbeatMsg = 'HeartBeat';

            const sendHeartbeat = () => {
                if (this.isOpen) {
                    uni.sendSocketMessage({
                        data: heartbeatMsg,
                    }).catch(error => {
                        console.log('发送心跳消息失败:', error);
                        this.reconnect()
                    });
                }
            };
            this.socketTimer = setInterval(sendHeartbeat, HEARTBEAT_INTERVAL);
        },

        // 开始重连
        reconnect () {
            if (!this.isOpen) {
                clearTimeout(this.socketTimer);
                this.socketTimer = setTimeout(() => {
                    console.log('开始重连...');
                    this.connectWebSocket();
                }, RECONNECT_INTERVAL);
            }
        },

        // 建立WebSocket连接
        connectWebSocket () {
            const that = this;
            
            uni.connectSocket({
                // 这里的值记得替换
                url: 'ws://8.888.888.888:8081/imserver/' + that.clientId,
                header: {
                    'content-type': 'application/json'
                },
            });

            uni.onSocketOpen(res => {
                console.log('连接成功!');
                that.isOpen = true;
                that.startHeartbeat();
            });

            uni.onSocketError(res => {
                console.log('连接失败!');
                that.isOpen = false;
                that.reconnect();
            });

            uni.onSocketClose(res => {
                console.log('连接关闭!');
                that.isOpen = false;
                that.reconnect();
            });

            uni.onSocketMessage(res => {
                if (res.data === 'HeartBeat') {
                    console.log(res.data, "心跳");
                    return;
                } else {
                    const data = JSON.parse(res.data);
                    console.log(data, "有新的消息");
                }
            });
        },
    },
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个示例代码,实现了Uniapp中封装WebSocket的功能,包括重连心跳功能,并可以在全局使用。 ```javascript // utils/websocket.js const HEARTBEAT_TIME = 30 * 1000 // 心跳时间间隔 class WebSocketUtil { constructor(url, options = {}) { this.url = url this.options = options this.socket = null this.isReconnecting = false // 是否正在重连 this.heartbeatInterval = null // 心跳定时器 } connect() { return new Promise((resolve, reject) => { this.socket = uni.connectSocket({ url: this.url, ...this.options, success: () => { this.initEvent() resolve() }, fail: reject, }) }) } initEvent() { this.socket.onOpen(() => { console.log('WebSocket连接已打开') this.startHeartbeat() // 开始心跳 }) this.socket.onClose((e) => { console.log('WebSocket连接已关闭', e) this.stopHeartbeat() // 停止心跳 if (!this.isReconnecting) { this.isReconnecting = true this.reconnect() // 重连 } }) this.socket.onError((e) => { console.log('WebSocket连接发生错误', e) this.stopHeartbeat() // 停止心跳 if (!this.isReconnecting) { this.isReconnecting = true this.reconnect() // 重连 } }) this.socket.onMessage((res) => { console.log('WebSocket收到消息', res) }) } reconnect() { setTimeout(() => { console.log('WebSocket正在重连...') this.connect().then(() => { console.log('WebSocket重连成功') this.isReconnecting = false }).catch(() => { console.log('WebSocket重连失败') this.reconnect() }) }, 3000) } startHeartbeat() { this.heartbeatInterval = setInterval(() => { if (this.socket.readyState === 1) { console.log('WebSocket发送心跳') this.socket.send({ type: 'heartbeat' }) } }, HEARTBEAT_TIME) } stopHeartbeat() { clearInterval(this.heartbeatInterval) } } export default { install(Vue) { const websocket = new WebSocketUtil('wss://example.com') Vue.prototype.$websocket = websocket websocket.connect() }, } ``` 使用时,在main.js中引入并注册即可: ```javascript // main.js import Vue from 'vue' import App from './App.vue' import websocket from './utils/websocket' Vue.config.productionTip = false Vue.use(websocket) new Vue({ render: h => h(App), }).$mount('#app') ``` 在组件中,可以通过`this.$websocket`来获取WebSocket实例,然后进行发送消息等操作: ```javascript // HelloWorld.vue export default { mounted() { this.$websocket.socket.send({ type: 'hello' }) } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值