sockjs前端WebSocket二次封装示例详解

 更新时间:2023年08月24日 11:17:44   作者:点墨  
这篇文章主要为大家介绍了sockjs前端WebSocket二次封装示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

业务需求

因业务需要,与后端进行websocket长连接通信,经过研究,决定使用sockjs-client和stompjs库,并进行了二次封装。

package.json版本:

"sockjs-client": "^1.5.1",
"stompjs": "^2.3.3",

socketManager.js

import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
import lodash from 'lodash';
function subscribeCallBack(data, subscribes) {
    if (data) {
        let topic = data.headers.destination;
        let funces = subscribes.get(topic);
        funces.forEach((func) => {
            func(data);
        });
    }
}
let clientManager = {
    client: null,
    connecting: false,//是否正在连接
    subscribes: new Map(),//订阅列表
    subscribe(topic, onMessage) {
        if (this.client != null && this.client.connected == true) {
            //已连接状态
            console.log('增加订阅 已连接状态');
            if (!this.subscribes.has(topic)) {
                this.client.subscribe(topic, (data) => subscribeCallBack(data, this.subscribes));
                this.subscribes.set(topic, [onMessage]);
            } else {
                let funces = this.subscribes.get(topic);
                funces.push(onMessage);
            }
        } else {
            //未连接状态
            console.log('增加订阅 未连接状态');
            if (!this.subscribes.has(topic)) {
                this.subscribes.set(topic, [onMessage]);
            } else {
                let funces = this.subscribes.get(topic);
                funces.push(onMessage);
            }
        }
    },
    subscribesAll() {
        console.log('订阅全部');
        if (lodash.isEmpty(this.client) || this.client.connected != true) {
            return;
        }
        let subscribes = this.subscribes;
        for (let topic of subscribes.keys()) {
            this.client.subscribe(topic, (data) => subscribeCallBack(data, subscribes));
        }
    },
    disconnect() {
        console.log('断开连接');
        if (lodash.isEmpty(this.client) || this.client.connected != true) {
            return;
        }
        this.client.disconnect();
        this.subscribes = new Map();
    },
    connect(onSuccess, onDisconnect) {
        try {
            if (this.connecting == true) {
                console.log('正在连接中');
                return;
            }
            this.connecting = true;
            if (lodash.isEmpty(this.client) || this.client.connected != true) {//未连接状态
                let socket = new SockJS('/bond/notification', null, { timeout: 6000 });
                let stompClient = Stomp.over(socket);
                stompClient.debug = null;
                console.log('开始连接');
                stompClient.connect
                    ({},
                        () => {
                            this.client = stompClient;
                            console.log('连接成功');
                            this.subscribesAll();//连接成功后开始订阅所有内容
                            if (onSuccess != null && onSuccess != undefined) {
                                onSuccess();
                            };
                        },
                        (error) => this.errorCallBack(error, onSuccess, onDisconnect)
                    );
            } else if (this.client != null && this.client.connected == true) {//已连接状态直接调用回调
                onSuccess();
            }
        }
        catch (err) {
            console.log('连接异常', err);
        }
        finally {
            this.connecting = false;
        }
    },
    errorCallBack(error, onSuccess, onDisconnect) {
        console.log('连接失败');
        if (onDisconnect != null && onDisconnect != undefined) {
            onDisconnect();
        }
        setTimeout(() => {//自动重连
            console.log('重新连接中');
            this.connect(onSuccess, onDisconnect);
        }, 10000);
    },
};
export default clientManager;

连接方式

useEffect(()=>{
    socketmanager.connect();
    return () => {
         socketmanager.disconnect();
    };
})

订阅方式

useEffect(() => {
        let topic = `/topic/notification`;
        socketmanager.subscribe(topic, (data) => {
            if (data) {
                //do something
            }
        })
    }, [])

如果有发现程序启动的时候报这个错误:

可能是后端返回时contentType不对导致stream流写入异常,修改后端后问题就可以解决。

以上就是sockjs前端WebSocket二次封装示例详解的详细内容,更多关于sockjs前端WebSocket二次封装的资料请关注脚本之家其它相关文章!

相关文章

最新评论