Giter Site home page Giter Site logo

gestureoflove's People

Contributors

alexz33 avatar

Watchers

James Cloos avatar  avatar

Forkers

yjc1972077620

gestureoflove's Issues

websocket

/**
 *  @desctiption: websocket实例提供模块
 *  @author:
 *  @date:
 */


define([], function(){

    var websocketProxy;

    var SocketFactory = function(options){

        var wsclass = Object.create({

            // 发送消息负载均衡判定维度
            sendedNum: 0,

            // 查询消息推送队列,如果新建完通道,通道还没打开,发送消息就过来了,就需要缓存查询条件,当通道打开完成后就推送所有消息
            sendStacks: [],

            // 是否已经开启
            isOpenStatus: false,

            pushSendStack: function(params){
                this.sendStacks.push(params)
            },

            // 实现化WebSocket对象,指定要连接的服务器地址与端口
            wsInstance: new WebSocket(options.serverIp)

        });
        $.extend(wsclass.wsInstance, {
            /**
             * 打开事件
             */
            onopen: function(){
                this.isOpenStatus = true;
                while(wsclass.sendStacks.length > 0){
                    this.send(JSON.stringify(wsclass.sendStacks.shift()));
                }

            }
        });
        $.extend(wsclass.wsInstance, options);

        return wsclass;

    };

    /**
     *
     * @constructor
     */
    var WebsocketProxy = function(){

        // WebSocket连接池
        this.wsSocketPool = {
            pool: [],
            // 游标指针
            lastCusor: null
        };
        // 参数发送缓存队列。网络断开后,重新连接通道后,需要把前面发送的请求参数重新发一遍
        this.resetSendStackCatch = [],

            // 回调函数集合
            this.messageListenerStack = [];

        this.init = function(options){
            // 最大通道连接数
            this.socketNumMax = options.socketNumMax || 5;
            // 通道服务端IP
            this.serverIp = options.serverIp;
            // 断开后监听服务端时间间隔
            this.reconnectTimeStep = options.reconnectTimeStep || 3000;
        }

    };
    /**
     *  与socket实例最消息监听相关的方法mixin集合
     */
    $.extend(WebsocketProxy.prototype, {

        socketNumMax: 5,

        serverIp: '',

        _isReadyConnect: true,
        /**
         * 通道消息监听方法
         */
        _onmessage: function(event){

            var data = JSON.parse(event.data);
            websocketProxy.messageListenerStack.forEach(function(fun){

                $.isFunction(fun) && fun(data);
            });

        },
        /**
         * 网络错误需要重新发起请求,重新发起连接
         * 需要清空连接池,及游标
         */
        _onclose: function(){
            websocketProxy.resetSocketPool();
            websocketProxy.websocketReconnect();

        },
        /**
         * 连接过程,如果网络不通则会被执行
         * @private
         */
        _onerror: function(){
            websocketProxy.resetSocketPool();
            websocketProxy.websocketReconnect();

        },
    });
    /**
     * websocket 重连接
     */
    $.extend(WebsocketProxy.prototype, {

        reconnectTimeStep: 3000,

        reconnectTime: null,

        websocketReconnectInstance: null,
        /**
         * WebSocket连接池重置
         */
        resetSocketPool: function(){

            this.wsSocketPool = {
                pool: [],
                // 游标指针
                lastCusor: null
            };

        },
        /**
         * 心跳重连接,发起一个
         */
        websocketReconnect: function(){

            var me = this;

            this.reconnectTime && clearTimeout(this.reconnectTime);
            this.reconnectTime = setTimeout(function(){
                // 对象放入连接池
                me.websocketReconnectInstance = SocketFactory({

                    serverIp: me.serverIp,
                    onopen: function(){
                        // 重连成功
                        me.resendSendStack();
                        me.websocketReconnectInstance.wsInstance.close();
                        me.reconnectTime && clearTimeout(this.reconnectTime);

                    },
                    onmessage: $.noop(),
                    onclose: $.noop(),
                    onerror: me._onerror
                });
            }, me.reconnectTimeStep);

        },

    });

    $.extend(WebsocketProxy.prototype, {

        /**
         *首先通过负载均衡算出找出当前需要发送消息的SocketInstance,如果不存在就新建
         * @returns {any}
         */
        getSocketInstance: function(){

            if(this.wsSocketPool.pool.length >= this.socketNumMax){

                // 游标取余数算法,在最大数量上+1取余
                var curCusor = this.wsSocketPool.lastCusor++ % (this.socketNumMax + 1);

                this.wsSocketPool.lastCusor = curCusor;

                return this.wsSocketPool.pool[curCusor];

            }else if(this.wsSocketPool.pool.length < this.socketNumMax){

                // 对象放入连接池
                var wsInstance = SocketFactory({
                    serverIp: this.serverIp,
                    onmessage: this._onmessage,
                    onclose: this._onclose,
                    onerror: this._onerror
                });
                this.wsSocketPool.pool.push(wsInstance);
                // 游标向下移一位
                this.wsSocketPool.lastCusor === null
                    ? this.wsSocketPool.lastCusor = 0
                    : this.wsSocketPool.lastCusor++;

                return wsInstance;
            }
        },
        /**
         * 重连后把缓存的查询条件重新发出
         */
        resendSendStack: function(){

            var me = this;
            me.resetSendStackCatch.forEach(function(parma){
                me._send(parma);
            });

        },
        /**
         * 取SocketInstance,然后发送请求消息
         * @param parma
         * @private
         */
        _send: function(parma){

            var wsInstance = this.getSocketInstance();
            if(wsInstance.isOpenStatus){
                console.log('message send');
                wsInstance.wsInstance.send(JSON.stringify(parma));
            }else{
                wsInstance.pushSendStack(parma);
            }

        },
        /**
         *  先预存参数,备网络断开时,再次连接后的参数发起
         * @param parma
         */
        send: function(parma){
            this.resetSendStackCatch.push(parma);
            this._send(parma);
        },

        /**
         * 通过key 、value方式记录所有组件的数据返回后的callback,
         * key为组件id,value为组件数据接收的callback
         * @param listener
         */
        registOnmessageListener: function(listener){

            this.messageListenerStack.push(listener);

        }
    });
    /**
     *  单实例工具方法,单例直接绑定在
     * @param instanceKey
     * @param Factory
     */
    function getSingleInstance(){

        if(!WebsocketProxy['websocketProxyInstance']){
            WebsocketProxy['websocketProxyInstance'] = new WebsocketProxy();
        }
        websocketProxy = WebsocketProxy['websocketProxyInstance'];
        return WebsocketProxy['websocketProxyInstance'];

    };

    return getSingleInstance();

});

````

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.