使用Promise封装Websocket

27次阅读

共计 2918 个字符,预计需要花费 8 分钟才能阅读完成。

await 后面若是跟的 Promise, 则接受Promise resolve 的值。Promise reject的值需要 try...catch 住,或者await 后面的表达式跟着.catch()


// 私有变量
const options = Symbol("options");
const intUniqueId = Symbol("intUniqueId");//
const arrQueueRequest = Symbol("arrQueueRequest");
const arrQueueNotice = Symbol("arrQueueNotice");


export default class SocketConn {
    /**
     * 构造函数,初始化数据
     * @param {*} objOption 
     */
    constructor(objOption) {this[options] = {
            connWbSK: null, //Websocket 实例
            secure: objOption.secure || "wss",
            hostName: objOption.hostName || "127.0.0.1",
            portNo: objOption.portNo || "80",
            user: objOption.user,
            password: objOption.password
        };
        this[intUniqueId] = 0; // 请求的 id,也是请求的 key 值(在请求序列里根据 id 找对应的包)this[arrQueueRequest] = {};// 请求序列
        this[arrQueueNotice] = {};//server 的通知序列};

    /*************** 私有函数 start*********** */
    /**
     * 处理请求对应的响应
     */
    _onRequestMessage = (objResp) => {let {id} = objResp;// 从响应里获取 id
        this[arrQueueRequest][id].resolve(objResp);// 只返回 resolve 函数,不 reject,可以在外面捕获
        delete this[arrQueueRequest][id];// 删除序列 id 对应数据包
    };

    _onNoticeMessage = (objResp) => {// 处理通知}

    /*************** 私有函数 end*********** */


    /*************** 公开函数 start*********** */
    // 公开函数
    open = (onSocketClose) => {
        //await 只能接收 resolve 的值,reject 的值需要在外面 catch
        return new Promise((resolve, reject) => {let _private = this[options],
                url = ""+ _private.secure +"://" + _private.hostName;
            if (_private.portNo) {url += ":" + _private.portNo;}
            url += "?";
            url += "user=" + _private.user;
            url += "&password=" + _private.password;
            _private.connWbSK = new WebSocket(url);
            
            _private.connWbSK.onopen = (event) => {// 成功连接上
                console.log("onopen")
                resolve(true);
            }

            _private.connWbSK.onmessage = (event) => {// 收到 server 发来的消息
                let objResp = JSON.parse(event.data);
                // 如果是我们发送的请求
                if(objResp.packet_type === "response"){this._onRequestMessage(objResp);
                }else{// 如果是 server 的通知
                    this._onNoticeMessage(objResp);
                }
            }

            _private.connWbSK.onerror = (event) => {// reject(false);
            };

            // 传入 onclose 事件,以便于 server 主动断开时触发
            _private.connWbSK.onclose = (event) => {onSocketClose(event); 
            };
        });
    };

    /**
     * 外部调用的发送方法
     */
    send = (serviceName, methodName, objData, dataFormat, timeout) => {return new Promise((resolve, reject) => {
            let objPkg, objPkgSendReq;
            this[intUniqueId] += 1;
            
            // 构建发送包
            objData = JSON.stringify(objData);// 先序列化
            objData = Base64.encode(objData);// 加密
            objPkg = {id: this[intUniqueId],
                packet_type: "request",
                service: serviceName,
                method: methodName,
                data: objData
            };

            objPkgSendReq = JSON.stringify(objPkg);
            this[arrQueueRequest][objPkg.id] = {
                id: objPkg.id,
                strReq: objPkgSendReq,
                reject: reject,
                resolve: resolve,
                dataFormat: dataFormat,
                timeoutId: null
            }
            this[options].connWbSK.send(this[arrQueueRequest][objPkg.id].strReq);
        })
    };

    // 主动关闭连接,并且重置数据
    closeSocketAndResetVar = () => {if(this[options].connWbSK){this[options].connWbSK.close();
            this[options].connWbSK = null;
        }
    };

    /*************** 公开函数 end*********** */
}

使用

    connectServer = async(options, onSocketClose) => {
        let socketConn = new SocketConn({
            hostName: options.hostName,
            portNo: options.portNo,
            secure: options.isSSL ? "wss" : "ws",
            user: options.user,
            password: options.password,
            resource
        }, onSocketClose);
        await socketConn.open(onSocketClose).catch(e){console.log(e)// 捕获 reject 错误
        };
        let data = { }
        await socketConn.send("","", data , "",).catch(e){console.log(e)// 捕获 reject 错误
        };
    }

正文完
 0