原文: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. Could not load type 'System.Reflection.AssemblySignatureKeyAttribute' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c

    错误: Could not load type 'System.Reflection.AssemblySignatureKeyAttribute' from assembly 'mscorlib, V ...

  2. Ubuntu 16 安装JDK1.8

    检查是否JDK已被安装: 上图表示没有安装,创建文件夹: 下载JDK: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-dow ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (34) ------ 第六章 继承与建模高级应用之多条件与QueryView

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-10  创建一个多条件过滤 问题 你想使用多个条件为实体过滤表中的行. 解决方案 ...

  4. Java批处理ExecutorService/CompletionService

    服务端接收一个请求,常常需要同时进行几个计算或者向其他服务发送请求,最后拼装结果返回上游.本文就来看下JDK提供几个并行处理方案,牵涉到ExcecutorService/CompletionServi ...

  5. 【PRINCE2是什么】PRINCE2认证之七大原则(2)

    我们先来回顾一下,PRINCE2七大原则分别是持续的业务验证,经验学习,角色与责任,按阶段管理,例外管理,关注产品,剪裁. 第二个原则:吸取经验教训. PRINCE2要求项目团队吸取以前的经验教训,在 ...

  6. Js toString()方法笔记

    一.前言 toString()用于将该对象以字符串(string)的形式返回,该方法属于Object对象;也就是说对象都能够使用此方法. 之前所接触的是array.toString()数组转换为字符串 ...

  7. OpenGL学习进程(13)第十课:基本图形的底层实现及算法原理

        本节介绍OpenGL中绘制直线.圆.椭圆,多边形的算法原理.     (1)绘制任意方向(任意斜率)的直线: 1)中点画线法: 中点画线法的算法原理不做介绍,但这里用到最基本的画0<=k ...

  8. Javascript算法系列之快速排序(Quicksort)

    原文出自: http://www.nczonline.net/blog/2012/11/27/computer-science-in-javascript-quicksort/ https://gis ...

  9. 【原创】开源Math.NET基础数学类库使用(14)C#生成安全的随机数

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

  10. MapReduce的理解

    1 什么是MapReduce? Map本意可以理解为地图,映射(面向对象语言都有Map集合),这里我们可以理解为从现实世界获得或产生映射.Reduce本意是减少的意思,这里我们可以理解为归并前面Map ...