原文: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. Web前端开发大系概览 (前端开发技术栈)

    前言 互联网建立50多年了,网站开发技术日新月异,但web前端始终离不开浏览器,最终还是HTML+JavaScript+CSS这3个核心,围绕这3个核心而开发出来大量技术框架/解决方案. 我从2000 ...

  2. iOS-----dSYM 文件分析工具

    来到新公司后,前段时间就一直在忙,前不久 项目 终于成功发布上线了,最近就在给项目做优化,并排除一些线上软件的 bug,因为项目中使用了友盟统计,所以在友盟给出的错误信息统计中能比较方便的找出客户端异 ...

  3. ArchLinux安装指南

    将ArchLinux作为进阶Linux发行版,主要看重滚动更新和深入理解Linux的安装过程. 由于是新手,所以先选择在公司电脑上用VMware来安装.然后渐进到借助U盘在win10笔记本上安装双系统 ...

  4. LINQ系列:LINQ to DataSet的DataTable操作

    LINQ to DataSet需要使用System.Core.dll.System.Data.dll和System.Data.DataSetExtensions.dll,在项目中添加引用System. ...

  5. 【Win10应用开发】自定义磁贴通知的排版

    前面老周用了两篇烂文,向大家介绍了Adaptive磁贴的模板使用.那些XML模板已经很强大了,不过,如果你觉得那些排版还不足以满足需求,不妨试试自己来定义磁贴的内容. 其实,Runtime App支持 ...

  6. lintcode循环数组之连续子数组求和

    v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. ...

  7. Web APi之认证(Authentication)及授权(Authorization)【一】(十二)

    前言 无论是ASP.NET MVC还是Web API框架,在从请求到响应这一过程中对于请求信息的认证以及认证成功过后对于访问页面的授权是极其重要的,用两节来重点来讲述这二者,这一节首先讲述一下关于这二 ...

  8. Web APi之手动实现JSONP或安装配置Cors跨域(七)

    前言 照理来说本节也应该讲Web API原理,目前已经探讨完了比较底层的Web API消息处理管道以及Web Host寄宿管道,接下来应该要触及控制器.Action方法,以及过滤器.模型绑定等等,想想 ...

  9. scikit-learn 线性回归算法库小结

    scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的不同和各自的使用场景. 线性回归的目的是要得到输 ...

  10. 在Linux中运行Nancy应用程序

    最近在研究如何将.NET应用程序移植到非Windows操作系统中运行,逐渐会写一些文章出来.目前还没有太深的研究,所以这些文章大多主要是记录我的一些实验. 这篇文章记录了我如何利用NancyFx编写一 ...