class My_Websocket {
    //#region 私有内部定义
    constructor(url, fun_msg, fun_state) {
        this._state = 0;
        this._lockReconnect = false;
        this._ws = null;
        this._wsUrl = url;
        this._fun_msg = null;

        this._heartCheck = {
            content: "heartBeat",
            timeout: 60 * 9,//9分钟发一次心跳
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function () {
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function (ws_obj) {
                let self_heart = this;
                this.timeoutObj = setTimeout(function () {
                    //这里发送一个心跳，后端收到后，返回一个心跳消息，
                    ws_obj.send(self_heart.content);
                    //如果超过一定时间还没重置(如果我没有收到后台给我心跳请求的响应)，说明后端主动断开了
                    self_heart.serverTimeoutObj = setTimeout(function () {
                        //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                        ws_obj.close();
                    }, self_heart.timeout * 1000);
                }, this.timeout * 1000);
            }
        };
        this._receive(fun_msg, fun_state);
    }

    // ws事件注册
    _initEventHandle(fun_state = () => { }) {
        let self = this;
        this._ws.onclose = function () {
            if (self._state !== 0) {
                self._state = 0;
                fun_state(0);
            }
            self._reconnect();
            console.log("ws连接关闭!" + new Date().toUTCString());
        };
        this._ws.onerror = function () {
            if (self._state !== 0) {
                self._state = 0;
                fun_state(0);
            }
            self._reconnect();
            console.log("ws连接错误!" + new Date().toUTCString());
        };
        this._ws.onopen = function () {
            if (self._state !== 1) {
                self._state = 1;
                fun_state(0);
            }
            //心跳检测重置
            self._heartCheck.reset().start(self._ws);
            console.log("ws连接成功!" + new Date().toUTCString());
        };
        this._ws.onmessage = function (event) {
            //如果收到的消息不是心跳消息,则回调给页面
            if (self._heartCheck.content !== event.data) {
                console.log("ws收到数据!" + event.data);
                self._fun_msg(event.data);
            }
            //如果获取到消息，心跳检测重置
            self._heartCheck.reset().start(self._ws);
            // 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
            window.onbeforeunload = function () {
                self._ws.close();
            };
        };
    }

    // ws重连
    _reconnect() {
        if (this._lockReconnect) return;
        this._lockReconnect = true;
        let self = this;
        setTimeout(function () {     //没连接上会一直重连，设置延迟避免请求过多
            self._receive();
            self._lockReconnect = false;
        }, 5000);
    }

    //接收消息
    _receive(fun_msg, fun_state) {
        fun_msg && (this._fun_msg = fun_msg);
        //关闭之前可能的链接
        this._ws && this._ws.close();
        try {
            if ('WebSocket' in window) {
                this._ws = new WebSocket(this._wsUrl);
            } else if ('MozWebSocket' in window) {
                this._ws = new MozWebSocket(this._wsUrl);
            } else {
                console.log("websocket 不被支持");
            }
            this._initEventHandle();
        } catch (e) {
            this._reconnect(fun_state);
            console.log(e);
        }
    }

    //#region 公有方法定义
    //发送消息
    send(text_msg) {
        if (this._ws.readyState === 1) {
            this._ws.send(text_msg);
        } else {
            console.log("ws 未连接");
        }
    }
    //关闭
    close() {
        if (this._ws.readyState === 1) {
            this._ws.close();
        } else {
            console.log("ws 未连接");
        }
    }
    // #endregion
}
export default My_Websocket