WebSocket 对象

let Socket = new WebSocket(url, [protocol] );

以上代码中的第一个参数 url, 指定连接的 URL。
第二个参数 protocol 是可选的,指定了可接受的子协议。

1、websocket事件;

let  socket = new WebSocket("//请求地址" ); // 定义socket 

socket.onopen           连接建立时触发
socket.onmessage        接收数据时触发
socket.onerror          通信错误时触发
socket.onclose          连接关闭时触发 

2、websocket状态码(socket.readyState,表示连接状态,可以是以下值)

 0:未连接(正在建立连接连接,还没有完成)
 1:连接已建立(连接成功建立,可以进行通信)
 2:连接正在关闭(连接正在进行关闭握手,即将关闭)
 3:连接已关闭或打不开连接( 连接已经关闭或者根本没有建立)

3、websocket方法;

 socket.send(); 向服务器发送数据
 socket.close();  关闭连接

封装

webSocket.js

/**
 * websocket相关方法类
 * websocket相关属性(仅供参考):
 * 在此新增、编辑、删除、获取websocket
 * 使用时直接使用 send方法即可,然后根据需要调用其他的方法
 * */
class WebsocketApi {
    constructor() {
        this.websocket = new Map(); //初始化websocket容器
        this.baseUrl = baseUrl; //默认URL,在config.js中配置,在main.js中注入
        this.isOpen = false; // 开启标识,连接标识 避免重复连接
        this.heartbeatInterval = 60000; //心跳发送频率,每段时间发送一次心跳包 这里设置为60s,不同于重连频率
        this.heartbeatData = null; // 心跳发送的数据内容
        this.heartbeatTimer = null; // 心跳timer
        this.heartbeat = null; //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
        this.isReconnect = true; // 是否自动重连
        this.reconnectInterval = 3000; // 重连频率,不同于心跳包发送时间间隔
        this.reconnectCount = 3; // 重连次数
        this.reconnectCurrent = 0; // 已发起重连次数
        this.reconnectTimer = null; // 重连timer
    }
    /**
     * 初始化websocket
     * @param url
     * websocket地址,默认为 this.baseUrl
     * @param callback
     * 初始化过程中的回调函数
     * 如果是普通字符串,则视为拼接到websocketURL后面的参数
     * @param callback:回调函数,用于获取onmessage事件返回的数据
     * @returns 无返回值
     */
    init(_url, callback) {
        const url = _url ? _url : this.baseUrl;
        if (!('WebSocket' in window)) {
            console.warn('浏览器不支持WebSocket');
            return;
        }

        // 已经创建过连接不再重复创建
        if (this.websocket) {
            return this.websocket;
        }

        this.websocket = new WebSocket(url);

        // 连接成功
        this.websocket.onopen = () => {
            console.log('连接成功');
            this.isOpen = true;
            this.isReconnect = true;
            // 开启心跳
            this.heartbeat();
        };

        this.websocket.onmessage = res => {
            this.getMessage(res, callback);
        };

        // 连接发生错误
        this.websocket.onerror = function (e) {
            console.error('WebSocket连接发生错误');
            if (!this.isOpen) {
                this.reconnect(url); //重连
            }
        };

        // 关闭连接
        this.websocket.onclose = e => {
            console.log(`连接已断开 (${e.code})`);
            clearInterval(this.heartbeatInterval);
            this.isOpen = false;

            // 需要重新连接
            if (this.isReconnect) {
                this.reconnectTimer = setTimeout(() => {
                    // 超过重连次数
                    if (this.reconnectCurrent > this.reconnectCount) {
                        clearTimeout(this.reconnectTimer);
                        return;
                    }

                    // 记录重连次数
                    this.reconnectCurrent += 1;
                    this.reconnect(url);
                }, this.reconnectInterval);
            }
        };
    }
    /**
     * 心跳方法,定时唤起连接
     * @returns 没有返回值
     */
    heartbeat() {
        this.heartbeat = setInterval(() => {
            if (this.isOpen) {
                this.send(this.heartbeatData);
            } else {
                this.clear();
            }
        }, this.heartbeatInterval);

        if (this.heartbeatTimer) {
            clearInterval(this.heartbeatTimer);
        }
        this.heartbeatTimer = setInterval(() => {
            this.send(this.heartbeatData);
        }, this.heartbeatInterval);
    }
    /**
     * 发送消息方法
     * @param data 要发送的数据内容
     * @param callback 发送之后的回调函数
     * @returns websocket实例或者undefined
     */
    send(data, callback) {
        // 开启状态直接发送
        if (this.websocket.readyState === this.websocket.OPEN) {
            this.websocket.send(JSON.stringify(data)); //在这里根据自己的需要转换数据格式

            if (callback) {
                callback();
            }

            // 正在开启状态,则等待1s后重新调用
        } else if (this.websocket.readyState === this.websocket.CONNECTING) {
            setTimeout(() => {
                this.send(data, callback);
            }, 1000);

            // 未开启,则等待1s后重新调用
        } else {
            this.init();
            setTimeout(() => {
                this.send(data, callback);
            }, 1000);
        }
    }
    /**
     * 接收消息方法
     * @param cb 接收到的消息后的回调函数
     * @returns websocket实例或者undefined
     */
    getMessage(cb) {
        this.websocket.onmessage = message => {
            try {
                const params = JSON.parse(message.data);
                if (params !== null && cb) {
                    return cb(params);
                } else {
                    return params;
                }
            } catch (error) {
                console.error(error);
            }
        };
    }
    /**
     * 重新连接的方法
     * @returns 没有返回值
     */
    reconnect(_url) {
        const url = _url ? _url : this.baseUrl;
        console.log('发起重新连接', this.reconnectCurrent);
        if (this.websocket && this.isOpen) {
            this.clear();
        }
        this.websocket = null;
        this.init(url);
    }
    /**
     * 清理websocket容器中连接已经关闭或者打开链接失败的websocket
     */
    clear() {
        this.websocket.close();
        this.heartbeat = null;
        this.heartbeatTimer = null;
    }
}
const websocketApi = new WebsocketApi();
export default websocketApi;

应用

例子1
<script src="./webSocket.js"></script>
<script type="text/javascript">

websocketApi.init();
websocketApi.clear();
websocketApi.getMessage(res => {
    console.log(JSON.parse(res.data));
});
websocketApi.send('1234');

</script>

Tom_Li
26 声望1 粉丝

热爱学习,热爱总结,热爱广博知识