socket.io,io=Manager(source, opts)
原文:http://www.cnblogs.com/xiezhengcai/p/3968067.html
当我们在使用
var socket = io("ws://103.31.201.154:5555");
的时候,socket.io都做了什么呢?建立socket连接,嗯 不错,但是我们还是得看看它是怎么实现的。
其实在socket.io里,io函数就是Manager函数,而Manager函数返回的就是Manager对象
function Manager(uri, opts){
//返回Manager对象
if (!(this instanceof Manager)) return new Manager(uri, opts);
if (uri && ('object' == typeof uri)) {
opts = uri;
uri = undefined;
}
opts = opts || {};
opts.path = opts.path || '/socket.io';
this.nsps = {};
//所有订阅socket状态的容器
this.subs = [];
this.opts = opts;
//是否重连
this.reconnection(opts.reconnection !== false);
//最大重连次数
this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
//两次重连之间的延迟
this.reconnectionDelay(opts.reconnectionDelay || 1000);
//两次重连之间的最大延迟
this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
//connection超时时间
this.timeout(null == opts.timeout ? 20000 : opts.timeout);
//连接状态
this.readyState = 'closed';
this.uri = uri;
//重连数
this.connected = 0;
//尝试次数
this.attempts = 0;
//与engine.io数据交互时数据要编码
this.encoding = false;
// packetBuffer
this.packetBuffer = [];
this.encoder = new parser.Encoder();
this.decoder = new parser.Decoder();
//是否自动连接
this.autoConnect = opts.autoConnect !== false;
//如果自动连接则开始连接
if (this.autoConnect) this.open();
}
代码中的注释已经很清楚了,但是值得一提的manager是对engine.io的一层封装,从客户端代码来看,在engine.io的基础上实现 自动重连机制。另外值得注意的是encoding、packetBuffer俩变量,当向engine.io传递数据时,我们要对数据进行encode,所以encoding是表示是否在对数据进行encode中,因为encoding是调用engine.io下的.write函数,同时也看出来,engine.io是socket.io的数据传输层。当数据在encode中时,encoding=true,如果当前正在encode中,那么新的数据就会被缓存到packetBuffer里,当encode结束会自动在packetBuffer里遍历进行encode(代码2)。另外subs数组装的是清除所有订阅socket状态的容器,如(代码1):
代码1
//清除socket连接超时计时器
this.subs.push({
destroy: function(){
clearTimeout(timer);
}
});
代码2
Manager.prototype.packet = function(packet){
debug('writing packet %j', packet);
var self = this;
if (!self.encoding) {
// encode,encoding标识为true
self.encoding = true;
this.encoder.encode(packet, function(encodedPackets) {
for (var i = 0; i < encodedPackets.length; i++) {
self.engine.write(encodedPackets[i]);
}
//encode结束,encoding置为false
self.encoding = false;
//查询队列执行packet
self.processPacketQueue();
});
} else { //如果在encode中,push到Buffer里
self.packetBuffer.push(packet);
}
};
在Manager的构造函数里,最后的结果是调用了open函数,这是打开socket连接的入口
Manager.prototype.open =
Manager.prototype.connect = function(fn){
debug('readyState %s', this.readyState);
//如果已经打开,直接返回
if (~this.readyState.indexOf('open')) return this; debug('opening %s', this.uri);
//打开socket连接
this.engine = eio(this.uri, this.opts);
var socket = this.engine;
var self = this;
this.readyState = 'opening'; // emit `open`
var openSub = on(socket, 'open', function() {
self.onopen();
fn && fn();
}); // emit `connect_error`
var errorSub = on(socket, 'error', function(data){
debug('connect_error');
self.cleanup();
self.readyState = 'closed';
self.emitAll('connect_error', data);
if (fn) {
var err = new Error('Connection error');
err.data = data;
fn(err);
} self.maybeReconnectOnOpen();
}); if (false !== this._timeout) {
var timeout = this._timeout;
debug('connect attempt will timeout after %d', timeout); // 设置连接超时
var timer = setTimeout(function(){
debug('connect attempt timed out after %d', timeout);
openSub.destroy();
socket.close();
socket.emit('error', 'timeout');
self.emitAll('connect_timeout', timeout);
}, timeout); this.subs.push({
destroy: function(){
clearTimeout(timer);
}
});
} this.subs.push(openSub);
this.subs.push(errorSub);
//返回Manager实例(已经打开socket连接的)
return this;
};
相信熟悉之前的代码后,阅读这部分代码轻松也很容易,通过engine.io打开socket连接,同时将readyState置于opening状态,也监听socket连接的状态信息,和刚才讲的一样,将清除监听放在subs容其中,在后续的代码可以看到有cleanup来执行容器里面的所有函数。这就不细讲了。
socket.io,io=Manager(source, opts)的更多相关文章
- 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?
通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...
- python全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
- python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)
昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...
- python网络编程-同步IO和异步IO,阻塞IO和非阻塞IO
同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...
- 事件,IO,select
事件驱动模型 对于普通编程来说,代码遵循线性流程:开始-->代码A-->代码B-->代码C-->...-->结束,编程者知道代码的运行顺序,由编程者控制 事件驱动模型,流 ...
- 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO
完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...
- Python 同步IO/异步IO了解
说明: 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间.所以说,当一个read操作发生时,它会经历两个阶段: 1. ...
随机推荐
- [VB] if 判断语句 和 If、IIf函数的比较
Module Module1 Sub Main() Dim s1 As String = "我是真的" Dim s2 As String = "我不是真的" D ...
- test markdown
Markdown和Haroopad介绍文档 [TOC "float:right"] 什么是Markdown Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John ...
- 了解Package Configurations
使用VS2010创建的SSIS Project有两种deployment model:project deployment 和 package deployment,默认是Project deploy ...
- LINQ系列:LINQ to SQL Concat/Union
1. Concat 单列Concat var expr = (from p in context.Products select p.ProductName) .Concat( from c in c ...
- Entity Framework Code First执行SQL语句、视图及存储过程
1.Entity Framework Code First查询视图 Entity Framework Code First目前还没有特别针对View操作的方法,但对于可更新的视图,可以采用与Table ...
- js实现图片轮播
效果图
- Objective-C中把数组中字典中的数据转换成URL
可能上面的标题有些拗口,学过PHP的小伙伴们都知道,PHP中的数组的下标是允许我们自定义的,PHP中的数组确切的说就是键值对.而在OC我们要用字典(Dictionary)来存储,当然了Java用的是M ...
- JavaScript(Node.js)+ Selenium自动化测试
Selenium is a browser automation library. Most often used for testing web-applications, Selenium may ...
- 重温Servlet学习笔记--servletContext对象
一个项目中只有一个ServletContext对象,我们可以在多个servlet中获取这个唯一的对象,使用它可以给多个servlet传递数据,我们通常成servletContext为上下文对象.这个对 ...
- Cesium原理篇:3最长的一帧之地形(1)
前面我们从宏观上分析了Cesium的整体调度以及网格方面的内容,通过前两篇,读者应该可以比较清楚的明白一个Tile是怎么来的吧(如果还不明白全是我的错).接下来,在前两篇的基础上,我们着重讨论一下地形 ...