原文: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)的更多相关文章

  1. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  2. python全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  3. 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

  4. 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...

  5. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  6. python网络编程-同步IO和异步IO,阻塞IO和非阻塞IO

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...

  7. 事件,IO,select

    事件驱动模型 对于普通编程来说,代码遵循线性流程:开始-->代码A-->代码B-->代码C-->...-->结束,编程者知道代码的运行顺序,由编程者控制 事件驱动模型,流 ...

  8. 理论铺垫:阻塞IO、非阻塞IO、IO多路复用/事件驱动IO(单线程高并发原理)、异步IO

    完全来自:http://www.cnblogs.com/alex3714/articles/5876749.html 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同 ...

  9. Python 同步IO/异步IO了解

    说明: 对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间.所以说,当一个read操作发生时,它会经历两个阶段: 1. ...

随机推荐

  1. 解决 Visual Studio 2017 RC 不兼容低版本 Visual Studio 创建的 MVC 4 项目的问题

    1.使用文本编辑器(如Visual Studio Code 或 notepad)打开 MVC 4 项目的 .csproj 文件 2.找到代码(可能会有不同)<ProjectTypeGuids&g ...

  2. AMD规范与CMD规范的区别

    AMD规范与CMD规范的区别是什么?    在比较之前,我们得先来了解下什么是AMD规范?什么是CMD规范?当然先申明一下,我个人也是总结下而已,也是网上看到的资料,自己总结下或者可以说整理下而已,供 ...

  3. 自定义函数执行动态sql语句

    --函数中不能调用动态SQL,使用用存储过程吧.如果还要对函数做其他操作,换成存储过程不方便,可以考虑把其他操作一起封装在存储过程里面.如:   create proc [dbo].[FUN_YSCL ...

  4. SQL Server 解读【已分区索引的特殊指导原则】(1)- 索引对齐

    一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...

  5. SqlServer索引的原理与应用

    索引的概念 索引的用途:我们对数据查询及处理速度已成为衡量应用系统成败的标准,而采用索引来加快数据处理速度通常是最普遍采用的优化方法. 索引是什么:数据库中的索引类似于一本书的目录,在一本书中使用目录 ...

  6. sizzle编译函数

    一个人去完成一件事情,如果派多个人去做的话,只要配合默契,效率比一个人做肯定要高,效率提高,所需的时间就减少了.如果只能一个人完成,那么必须设法提高自己的劳动效率,这个提高可以是量的改变也可以是质的改 ...

  7. XSD文件生成C#VO实体类

    最近公司要做一个项目,需要和现有的其他项目对接,由于不知道他们的数据库,只有XSD文件.所以,我们在修改相应的程序时,就需要根据他们提供的XSD文件,来写我们的VO实体类,由于我写过根据Oracle数 ...

  8. SQL Server 存储过程生成insert语句

    你肯定有过这样的烦恼,同样的表,不同的数据库,加入你不能执行select  insert 那么你肯定需要一条这样的存储过程,之需要传入表明,就会给你生成数据的插入语句. 当然数据表数量太大,你将最好用 ...

  9. scikit-learn 支持向量机算法库使用小结

    之前通过一个系列对支持向量机(以下简称SVM)算法的原理做了一个总结,本文从实践的角度对scikit-learn SVM算法库的使用做一个小结.scikit-learn SVM算法库封装了libsvm ...

  10. MVC, MVP, MVVM比较以及区别(上)

    MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...