基于事件驱动的前端通讯框架(封装socket.io)

socket.io的使用能够很轻松的实现websockets,兼容全部浏览器,提供实时的用户体验,而且为程序员提供客户端与服务端一致的编程体验。可是在使用socket.io的过程当中,因为业务需求须要同时发起几个请求,并等待数据返回调用相对应的回调函数执行,那么在数据返回时,你如何知道这个数据是要用于那个回调函数的,也就是说该去执行那个回调函数来处理返回来的数据?在使用AS过程当中发现,AS的事件机制是一个很灵活的东西,你能够自定义多个事件监听,而后在派发事件的时候会根据你派发的事件调用相对应的回调函数。那么如何把这一东西用到socket.io中呢,就是若是发送某个请求时同事让它与它须要回调的函数关联,那么在请求返回数据的时候我就能够根据这个关联找到它要回调的函数并执行。就像AS的事件机制同样,你为某个事件添加了监听,那么当这个事件派发出来的时候就会去调用相对应的回调函数。为了实现这一目的我作了如下几个东西。程序员

首先是Event类:web

/** * 事件类 */
var Event = function (type, data,cancelable) { this.cancelable = cancelable; //是否取消传递
    this.type = type; //类型
    this.data = data; // 数据

    /// <summary>
    /// 复制
    /// </summary>
    /// <returns type="Event">复制后的元素</returns>
    this.clone = function() { var that = new Event(); that.cancelable = this.cancelable; that.type = this.type; that.data = this.data; return that; }; this.toString = function() { return "Event( type: " + this.type + ", cancelable: " + this.cancelable + this.eventPhase + ")"; }; };

 

接着是EventListener :
/** * 事件监听类 * @param listener 监听回调函数 * @param priority 优先级 */
var EventListener = function (listener,priority) { if (typeof(arguments[0]) != "function") { throw new Error("必须指明listener"); } this.listener = listener; this.priority = priority?priority:0; };

 

再接着是EventManager,用于关联事件和它对应的回调 :编程

var EventManager = { eventListeners : [], /// <summary>
    /// 添加事件处理函数
    /// </summary>
    /// <param name="type">类型</param>
    /// <param name="listener">处理函数</param>
    /// <param name="priority">优先级,默认为0</param>
    addEventListener : function (type, listener, priority) { if (typeof (arguments[1]) != "function") { throw new Error("必须指明type和listener"); } if (!this.eventListeners[type]) { this.eventListeners[type] = []; } var index = this.eventListeners[type].length; console.log(type + "监听个数:" + index); //防止重复监听
        for (var i = 0; i < index; i++) { var temp = this.eventListeners[type][i]; if (temp.listener == listener) { return; } } var eventListener = new EventListener(listener, priority); this.eventListeners[type].push(eventListener); this.eventListeners[type].sort(function (a, b) { return a.priority - b.priority; }); }, /// <summary>
    /// 移除监听器
    /// </summary>
    /// <param name="type">类型</param>
    /// <param name="listener">监听器</param>
    removeEventListener : function (type, listener) { var len = arguments.length; if (len < 2) { throw new Error("必须指定type 与 listener"); } if (!this.eventListeners[type]) { return; } var index = this.eventListeners[type].length; //若是数组长度为0,删掉整个数组
        if (index == 0) { var lisIndex = this.eventListeners.length; for (var i = 0; i < lisIndex; i++) { if (type == this.eventListeners[i]) { this.eventListeners.splice(i, 1); } } } else { for (var j = 0; j < index; j++) { var temp = this.eventListeners[type][0]; if (temp.listener == listener) { this.eventListeners[type].splice(0, 1); } } } }, /// <summary>
    /// 分派一个事件
    /// </summary>
    /// <param name="event">事件</param>
    dispatchEvent : function (event) { // 若是event不是一个Event类,则默认是字符串,做为事件标识建立一个新的Event(event)
        event = (typeof (event) == "string") ? new Event(event) : event; if (!this.eventListeners[event.type]) { return; } var index = this.eventListeners[event.type].length; for (var k = 0; k < index; k++) { var temp = this.eventListeners[event.type][k]; if (temp.listener) { if (!event.cancelable) { temp.listener(event); } else { continue; } } } }, /// <summary>
    /// 判断是否具备该事件的处理器
    /// </summary>
    /// <param name="type">事件类型</param>
    /// <returns type="boolean">判断是否具备该事件的处理器</returns>
    hasEventListener : function (type) { return this.eventListeners[type] && this.eventListeners[type].length > 0; } };

接着是各个不一样的数据请求,例如增删改查命令json

var RequestManager = { sendData: function (eventType, params, listener, priority) { EventManager.addEventListener(eventType, listener, priority); console.log("发包,事件:" + eventType); var json = { eventType: eventType, parameters: params }; SocketManager._instance.json.send(json); }, readData: function (data) { var evt = new Event(); evt.type = data.eventType; evt.data = data; EventManager.dispatchEvent(evt); } };

 

再来是SocketManager,对socket.io进行封装,这里至关因而单例的实现,保证了应用中只存在一个socket:数组

var SocketManager = { _instance: null, connect: function (ip,port) { if (_instance) { return; } _instance = io.connect("http://" + ip + ":" + port); _instance.on("connect", function (data) { console.log("Connected to Server"); }); _instance.on("message", function (data) { console.log("readData:" + data); RequestManager.readData(data); }); _instance.on('reconnect', function () { console.log("reconnect to Server"); }); } };

使用起来也很是简单,经过调用SocketManager.connect(ip,port);便可实例化一个socket,再来经过RequestManager.sendData("getData1", params, getData1Handler, 0);既可完成数据访问,但同时有不少个请求时,如RequestManager.sendData("getData2", params, getData2Handler, 1);RequestManager.sendData("getData3", params, getData3Handler, 2);一样能够根据数据的eventType类型调用对应的回调函数。浏览器

相关文章
相关标签/搜索