原文: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;// packetBufferthis.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标识为trueself.encoding = true;this.encoder.encode(packet, function(encodedPackets) {for (var i = 0; i < encodedPackets.length; i++) {self.engine.write(encodedPackets[i]);}//encode结束,encoding置为falseself.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来执行容器里面的所有函数。这就不细讲了。

转载于:https://www.cnblogs.com/xiezhengcai/p/3968067.html

socket.io,io=Manager(source, opts)相关推荐

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

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

  2. 分不清楚阻塞IO,非阻塞IO,IO复用?用最贴近生活的例子带你理解这三者的区别!

    文章目录 前言 一.什么是IO 二.阻塞IO模型 三.非阻塞 IO模型 四.IO复用模型 总结 前言 在<Unix网络编程>一书中提到了五种IO模型,分别是:阻塞IO.非阻塞IO.IO复用 ...

  3. 高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

    高级IO: 五种典型IO: 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型:select/poll/epoll 五种典型IO 阻塞IO IO操作的流程:等待IO操作条件具 ...

  4. 阻塞和非阻塞IO,异步和同步IO

    从网上看到一遍比较好的博客介绍阻塞和非阻塞IO,异步和同步IO的区别和各自的使用场景,虽然是从网络套接字方面解析的,不过也是适合于对驱动文件的操作,毕竟套接字的本质也是一个文件描述符. 转载内容 本文 ...

  5. 计算机网络(6) ——同步IO/异步IO专题

    计算机网络(6) --同步IO/异步IO专题 文章目录 理解性记忆 计算机网络(6) --同步IO/异步IO专题 1.同步IO 2.异步IO 理解性记忆 计算机网络(6) --同步IO/异步IO专题 ...

  6. 10-线程,进程,协程,IO多路复用

    - 线程进程介绍 1. 工作最小单元是线程 2. 应用程序 -> 至少有一个进程 -> 至少有一个线程 3. 应用场景: IO密集型:线程 计算密集型:进程 4. GIL,全局解释器锁. ...

  7. 多线程,io,网编,反射,xml

    代码全部手敲,永远不要相信你看到的结论,自己编码后运行出来的,才是自己的.1111111111111111111111111111111111111111111111 1111111111111111 ...

  8. day04--java高级编程:API:Object、String,Buffer、包装类、日期、java比较器、BigInteger、进制、length区别,IO流,路径,序列化id,编码

    1 API 1.1 Api文档下载 1.API (Application Programming Interface,应用程序编程接口)是 Java 提供的基本编程接口,一切可以调用的东西都是API. ...

  9. 【Note4】网络,并发/IO,内存,linux/vi命令,正则,Hash,iNode,文件查找与读取

    文章目录 1.局域网:CSMA/CD 2.互联网:ARP,DHCP,NAT 3.TCP协议:telnet,tcpdump,syn/accept队列 4.HTTPS协议:摘要(sha.md5.crc). ...

最新文章

  1. 第六周实践作业:软件测试和评估
  2. windows环境下bat和python调用rysnc的方式
  3. Spring boot登录错误提示
  4. i-i.me:网址导航真的是伪需求吗?
  5. 学了C++不会STL,简直少了左膀右臂
  6. [Redis6]常用数据类型_Zset有序集合
  7. 微信时代计算机教学,互联网+时代技工院校计算机教学方式研究
  8. 学习笔记 04----声明和类
  9. Anconda之常用命令汇总
  10. WPF 邮箱输入框提示 和 手机号码验证 .
  11. 解决 VS2008安装过程更改路径的问题
  12. 【SA TSP】基于matlab模拟退火算法求解34城市旅行商问题【含Matlab源码 882期】
  13. 使用Python绘制二元函数图像
  14. Prefix Sum —— 树状数组+懵逼的组合恒等式
  15. Mac电脑高效办公必备武器——雷神Thor
  16. 点、线、三角形(C++)
  17. 【数据分析】【MySQL】快速入门+案例+代码+命令整理+GIF实操演示
  18. window常用自带工具
  19. java之 ------ 枚举类型
  20. nginx配置静态资源,重新发布后,浏览器缓存导致异常原因和解决

热门文章

  1. cv2.matchTemplate()函数的应用,匹配图片后画出矩形
  2. Hackerrank GCD Product(莫比乌斯反演)
  3. HDU 2079 选课时间
  4. 查找运行时间超过1天的frmweb进程
  5. Python之几种常用模块
  6. 数组去重--这几种方法够不?
  7. 算法-------矩阵中的最长递增路径(Java版本)
  8. 算法--------------整数反转
  9. 如何让Android对话框全屏 Dialog 全屏
  10. Android属动画ObjectAnimator和ValueAnimator应用