使用Promise封装Websocket

时间: 2019-07-10阅读: 935标签: socket

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错误
        };
    }
站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/5227

Nginx 转发 socket 端口配置

Nginx 转发 socket 端口常见场景:在线学习应用,在常规功能之外,增加一个聊天室功能,后端选择 swoole 提供服务提供者,同时不想前端直接 ip:port 方式链接到服务,需要使用 Nginx 进行转发。

轮询、长轮询、长连接、socket连接、WebSocket

轮询:客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并关闭连接;长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接

websocket.io

服务器端:使用express服务;简单的使用websocket.io;使用命名空间 实例中两个命名空间info job;客户端 vue为例引入socket.io-client

web Socket和Socket.IO框架

HTTP无法轻松实现实时应用:HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接。我们可以非常轻松的捕获浏览器上发生的事件(比如用户点击了盒子)

socket.io的接入使用

传统的客户端和服务器通信协议是HTTP:客户端发起请求,服务端进行响应,服务端从不主动勾搭客户端。这种模式有个明显软肋,就是同步状态。而实际应用中有大量需要客户端和服务器实时同步状态的场景

封装小程序的websocket

这两天的工作中,我重构了一个项目里的客服聊天功能,是小程序的,用了小程序提供的websocket有关的接口,我感觉很简单,和web端的接口大体一致,不过我喜欢封装后去使用,封装成一个类,创建一个类的实例

Vue.js 如何使用 Socket.IO

Socket.IO是一个WebSocket库,可以在浏览器和服务器之间实现实时,双向和基于事件的通信。它包括:Node.js服务器库、浏览器的Javascript客户端库。它会自动根据浏览器从WebSocket、AJAX长轮询、

Socket通信原理.一文了解Socket

Socket 的中文翻译过来就是“套接字”。套接字是什么,我们先来看看它的英文含义:插座。Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通信,端口就像插座上的孔,端口不能同时被其他进程占用。而我们建立连接就像把插头插在这个插座上

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广