美文网首页
webSocket使用

webSocket使用

作者: 熊少年 | 来源:发表于2018-08-17 18:31 被阅读47次

随着互联网的快速发展,程序员需要处理的业务场景也越来越多了,ajax对于一些常链接实时刷新数据特殊的场景的处理就显的很无力,于是webSocket出现了。
这次的博客将以websocket的链接,发送,监听,关闭,重连,重发几个步骤来讲解一下websocket的使用。
我将会封装一个websocket的构造函数来讲。

1 构建获取基本信息

class LangWs {
    constructor(url) {
        this.ws = '';
        this.url = url;
        this.connect()
    }

    connect() { // ws链接
        this.ws = new WebSocket(this.url)
    }

    wsStatus() {  // ws状态
        return this.ws.readyState
    }
}

2 发送消息

class LangWs {
    constructor(url) {
        this.ws = '';
        this.url = url;
        this.connect()
    }

    connect() {
        this.ws = new WebSocket(this.url);
    }

    send(args) { // 发送
        this.ws.send(args)
    }

    wsStatus() {
        return this.ws.readyState
    }
}

3 接受

class LangWs {
    constructor(url) {
        this.ws = '';
        this.handers = new Map(); // 处理回调函数
        this.url = url;
        this.connect()
    }

    connect() {
        this.ws = new WebSocket(this.url);
        this.ws.onmessage = (event) => {
            // 解析发过来的数据,看情况解压
            if (this.handers.has(event.data.cmd)) {
                this.handers.get(event.data.cmd)()
            }
        };
    }

    send(args) {
        this.ws.send(args)
    }

    addHandler(cmd, fn) {
       this.handers.set(cmd,fn)
    }

    wsStatus() {
        return this.ws.readyState
    }
}

4 关闭

class LangWs {
    constructor(url) {
        this.ws = '';
        this.forceClose=false; // 用于判断是否重连
        this.handers = new Map(); 
        this.url = url;
        this.connect()
    }

    connect() {
        this.ws = new WebSocket(this.url);
        this.ws.onmessage = (event) => {
            // 解析发过来的数据,看情况解压
            if (this.handers.has(event.data.cmd)) {
                this.handers.get(event.data.cmd)()
            }
        };
    }

    send(args) {
        this.ws.send(args)
    }

    addHandler(cmd, fn) {
       this.handers.set(cmd,fn)
    }
    close() {
        if (this.ws) {
            this.forceClose = true;
            this.ws.close()
        }
    }
    wsStatus() {
        return this.ws.readyState
    }
}

5 重连

class LangWs {
    constructor(url) {
        this.ws = '';
        this.forceClose=false; // 用于判断是否重连
        this.reconnectInterval=1000; // 用于重连
        this.handers = new Map(); 
        this.url = url;
        this.connect()
    }

    connect() {
        this.ws = new WebSocket(this.url);
        this.ws.onmessage = (event) => {
            // 解析发过来的数据,看情况解压
            if (this.handers.has(event.data.cmd)) {
                this.handers.get(event.data.cmd)()
            }
        };
       this.ws.onclose = () => {
            if (this.forceClose) return; // 手动关闭,则关闭
            setTimeout(() => { // 重连
                this.connect();
            }, this.reconnectInterval);
        }
    }

    send(args) {
        this.ws.send(args)
    }

    addHandler(cmd, fn) {
       this.handers.set(cmd,fn)
    }
    close() {
        if (this.ws) {
            this.forceClose = true;
            this.ws.close()
        }
    }
    wsStatus() {
        return this.ws.readyState
    }
}

6 重发以及其他一些判断(都有备注)

class LangWs {
    constructor(url) {
        this.ws = ''; // ws实例
        this.wsStatus = ''; // ws状态
        this.reconnectInterval = 1000; // 重发事件
        this.forceClose = false; // 判断是否重发
        this.handers = new Map(); // 处理发送事件集合
        this.subChannels = new Map(); // 重发事件集合
        this.url = url;  // ws url
        this.connect()  // 连接函数
    }

    connect() {
        this.ws = new WebSocket(this.url);
        this.wsStatus = this.ws.readyState;
        if (this.wsStatus > 1) {
            if (this.forceClose) {
                return;
            }
        }
        this.ws.onopen = () => {  // 处理open事件
            if (this.subChannels && this.subChannels.size) {   // 重发事件
                this.subChannels.forEach((item) => {
                    const args = {
                        event: 'sub',
                        params: item
                    };
                    this.send(JSON.stringify(args));
                });
            }
        };
        this.ws.onmessage = (event) => { // 处理回调函数
            // 解析发过来的数据,看情况解压
            if (this.handers.has(event.data.cmd)) {
                this.handers.get(event.data.cmd)()
            }
        };
        this.ws.onclose = () => {  // 判断是否重发
            if (this.forceClose) return;
            setTimeout(() => {
                this.connect();
            }, this.reconnectInterval);
        }
    }

    send(args) {  // 发送数据
        if (this.wsStatus === WebSocket.OPEN) {
            this.ws.send(args);
            this.resetSub(args.cmd)  //记录发过的消息
        }
    }
 // 添加处理函数
     addHandler(cmd, fn) {
       this.handers.set(cmd,fn)
    }

    removeHandler(cmd) {  // 删除处理函数
        if (cmd) {
            this.handers.delete(cmd); // 删除事件
            if (this.subChannels.has(cmd)) {
                this.subChannels.delete(cmd);
            }
        }
    }

    resetSub(data) {  // 消息处理函数
        if (typeof data !== 'string') {
            return;
        }
        const reqData = JSON.parse(data);
        if (reqData.event === 'sub') {  // 处理添加事件
            this.subChannels.set(cmd, reqData.params);
        }

    }

    close() {  // 主动关闭
        if (this.ws) {
            this.forceClose = true;
            this.ws.close()
        }
    }
}

还有一些心跳检查,事件处理可以自行配置,这个配置已经适合绝大多数场景了

最后在加一个使用案例;根据自己的数据格式来,做一些适当的改进。

import {LangWs} from './ws'  // 写入自己文件路径

const socket = new LangWs('ws://localhost8080:80');
const args = {
    id: '12121',
    cmd: 'qqqqqqq'
};
socket.send(args);
socket.addHandler(args.cmd, (data) => {
    console.log(11)  // 这里处理自己的业务
});
socket.removeHandler(args.cmd);  //在自己需要的地方断开
socket.close();  //在自己需要的地方关闭连接

相关文章

网友评论

      本文标题:webSocket使用

      本文链接:https://www.haomeiwen.com/subject/yzltiftx.html