RN开发中使用websocket,会出现一个严重问题,部分手机会经常出现多次发送或多次接收消息。搜索一翻后以下代码因该可以有效解决此问题,在此记录以备后用。

重点是websocket要使用单例模式,以防止多次实例造成的重复连接

React Native 客户端代码WebSocketClient.js

import {DeviceEventEmitter} from 'react-native';
const url = 'ws://xxx.xxx.xxx.xxx';
let that = null;
export default class WebSocketClient {
    constructor() {
        this.ws = null;
        that = this;
    }
 
    /**
     * 获取WebSocket单例,这里是重点
     * @returns {WebSocketClient}
     */
    static getInstance() {
        if (!this.instance) {
            this.instance = new WebSocketClient();
        }
        return this.instance;
    }
 
    /**
     * 初始化WebSocket
     */
    initWebSocket() {
        try {
            //timer为发送心跳的计时器
            this.timer && clearInterval(this.timer);
            this.ws = new WebSocket(url);
            this.initWsEvent();
        } catch (e) {
            console.log('WebSocket err:', e);
            //重连
            this.reconnect();
        }
    }
 
    /**
     * 初始化WebSocket相关事件
     */
    initWsEvent() {
        //建立WebSocket连接
        this.ws.onopen = function () {
            console.log('WebSocket:', 'connect to server');
        };
 
        //客户端接收服务端数据时触发
        this.ws.onmessage = function (evt) {
            if (evt.data !== 'pong') {
                //不是心跳消息,消息处理逻辑
                console.log('WebSocket: response msg', evt.data);
                //接收到消息,处理逻辑...
                //更新广播
                DeviceEventEmitter.emit('pushEmitter', '');
            } else {
                console.log('WebSocket: response pong msg=', evt.data);
            }
        };
        //连接错误
        this.ws.onerror = function (err) {
            console.log('WebSocket:', 'connect to server error');
            //重连
            that.reconnect();
        };
        //连接关闭
        this.ws.onclose = function () {
            console.log('WebSocket:', 'connect close');
            //重连
            that.reconnect();
        };
 
        //每隔15s向服务器发送一次心跳
        this.timer = setInterval(() => {
            if (this.ws && this.ws.readyState === WebSocket.OPEN) {
                console.log('WebSocket:', 'ping');
                this.sendMessage('ping');
            }
        }, 15000);
    }
 
    //发送消息
    sendMessage(msg) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            try {
                this.ws.send(msg);
            } catch (err) {
                console.warn('ws sendMessage', err.message);
            }
        } else {
            console.log('WebSocket:', 'connect not open to send message');
        }
    }
 
    //重连
    reconnect() {
        if (this.timeout) {
            clearTimeout(this.timeout);
        }
        this.timeout = setTimeout(function () {
            //重新连接WebSocket
            this.initWebSocket();
        }, 15000);
    }
}
分类: ReactNative 标签: 暂无标签

评论

暂无评论数据

暂无评论数据

目录