cocos creator中websocket单例模式正确姿势(不用挂到Scene上,直接getInstance就行)

【推荐阅读】微服务还能火多久?>>>

let websocket = cc.Class({
    extends: cc.Component,

    properties: {
        _sock: null,
        _services_handler: null,
        _msg_queue: [],

        is_lock: false,
    },

    onLoad: function () {
        console.log("websocket onLoad");
    },

    onDestroy: function () {
        console.log("websocket onDestroy");
    },

    lock: function () {
        this.is_lock = true;
    },

    unlock: function () {
        this.is_lock = false;
    },

    update: function () {
        if (this.is_lock) {
            return;
        }

        if (this._msg_queue.length > 0) {
            // 从消息队列中取得一个消息
            let obj_data = this._msg_queue.shift();

            let ctype = obj_data.ctype;
            let body = obj_data.body;

            // 有错误
            if (body.errormsg) {
                console.error("[", ctype, "]", body);
                return;
            }
            console.log("[", ctype, "]", body);


            if (this._services_handler[ctype]) {
                this._services_handler[ctype](ctype, body);
            } else {
                console.warn(ctype, "客户端没有注册!!!");
            }
        }
    },

    on_open: function () {
        console.log("连接服务器成功!!!");
    },

    on_message: function (event) {
        if (!this._services_handler) {
            return;
        }

        let obj_data = JSON.parse(event.data);
        this._msg_queue.push(obj_data);
    },

    on_close: function () {
        console.log("on_close!!!");
        this.close();
    },

    // 比如没有连上
    on_error: function () {
        console.log("on_error!!!");
        this.close();
    },

    close: function () {
        if (this._sock) {
            this._sock.close();
            this._sock = null;
        }
    },

    connect: function (url) {
        this._sock = new WebSocket(url);

        this._sock.binaryType = "arraybuffer";

        this._sock.onopen = this.on_open.bind(this);
        this._sock.onmessage = this.on_message.bind(this);
        this._sock.onclose = this.on_close.bind(this);
        this._sock.onerror = this.on_error.bind(this);
    },

    send_data: function (obj_data) {
        if (!this._sock || this._sock.readyState != WebSocket.OPEN) {
            console.error("尚未连接服务器!!!");
            return;
        }
        let json_data = JSON.stringify(obj_data);
        this._sock.send(json_data);
    },

    register_services_handler: function (services_handler) {
        this._services_handler = services_handler;
    },

    remove_services_handler: function () {
        this._services_handler = null;
    }
});

websocket._instance = null;
websocket.getInstance = function () {
    if (!websocket._instance) {
        let node = new cc.Node();
        websocket._instance = node.addComponent(websocket);
        cc.game.addPersistRootNode(node);
    }

    return websocket._instance;
};

module.exports = websocket;