概述:

首先,我们知道,起初的http协议只是为了能够进行通信而被创造出来(也就是请求-响应的过程)。并没有双向通信这一说,后面随着历史业务的需求,人们使用轮询http来解决双向通信也就是使用xhr或者jsonp的方法进行发送请求到服务端并且进行回调获取服务端数据

通信的几个名称:

单工通讯:既只能客户端向服务端发送数据或者服务端向客户端发送数据(如广播,电视之类的,他可以给你传播信息,你却不能给他回应)

半双工单向通讯:客户端可以向服务端发送数据,服务端也可以向客户端发送数据,但是不能同时,只能这一端发送完后另一端才可以进行响应(对讲机,他讲一句你讲一句,但是不能同时讲)

全双工通讯:客户端可以向服务端发送数据,服务端也可以向客户端发送数据,可以同时进行(电话,qq聊天等等,可以同时讲或者发送消息)

1:轮询:隔一段时间进行一次查询或者询问


轮询分为长轮询和短轮询,长轮询是基于短轮询的一个优化结果。

短轮询:

通过客户端定期轮询来询问服务端是否有新的信息产生,如果有则返回,没有就不响应,

缺点:也是显而易见,轮询间隔大了则信息不够实时,轮询间隔过小又会消耗过多的流量,增加服务器的负担。

长轮询:

是需要服务端进行更改来进行支持,客户端向服务端发送请求时,如果此时服务端没有新的信息产生,并不立刻返回,而是Hold住一段时间等有新的信息或者超时再返回,客户端收到服务器的应答后继续轮询。可以看到长轮询比短轮询可以减少大量无用的请求,并且客户端接收取新消息也会实时不少。减少http请求对性能的优化是很有利的,所以他是短轮询上的一个优化

缺点:终归来讲还是一个http请求,只是进行了变化而已,而且如果客户端不请求,服务端有数据的话,也会一直累积在那,不能实现实时的双向通信

此时的webSocket也就应需而生


2:webSocket协议原理


webSocket也是基于Tcp协议传输层连接的,跟http相同处于协议应用层,而且它还是基于http的握手的,只是是握手的时候会传输特定的数据让协议升级成为webSocket协议

与http与之不同的是webSocket是一个持久化协议,而http协议是一个非持久化协议,也就是http他请求然后响应就结束了,而webSocket会一直保持连接而且一直传输数据,直到你将连接断开

websocket连接过程:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Y3JJCMbDL1IDUCH9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 20

其中的这俩段代码就是将http升级为webSocket的关键

Upgrade: websocket
Connection: Upgrade

而后面的三行代码则是一些验证信息

  • Sec-WebSocket-Key:浏览器随机生成,用于给服务端使用,如果服务端支持webSocket,服务端会对该数据进行一些处理然后返回给客户端进行验证
  • Sec-WebSocket-Protocol:是一个列表,列表中列出客户端所支持的协议
  • Sec-WebSocket-Version:指定版本

然后服务端就会返回

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

服务端返回这俩段代码就说明升级成功

Upgrade: websocket
Connection: Upgrade
  • Sec-WebSocket-Accept:对Sec-WebSocket-Key进行处理后的数据。用于证明他是支持升级后的协议的,验证成功
  • Sec-WebSocket-Protocol:服务端最终选定的协议

做完这些以后这次连接之后就都是webSocket连接了

3:socket.io原理

介绍

首先,socket.io是一个库,一个基于engine.io协议(封装了webSocket协议)的库,在协议上创建了Engine.io引擎,socket.io则是该引擎的应用层框架

它相对比原生webSocket的一些特性

  • 长轮询回退:如果无法建立webSocket连接,socket.io将会退回到http长轮询进行连接,这也是为了兼容一些特别老的项目和极少数不支持的浏览器(现如今)
  • 自动连接:在一些情况下,连接某一方有可能在不知情的情况下断开,它有一个心跳机制,可以定时去监测是否连接,只要不是客户端主动关闭连接,socket.io就会在连接出错后不断重试以建立连接,服务端数据会进行自动缓冲,直到再次连接,为了防止断开时间过长,缓冲时间过长,可以利用使用Socket 实例的connected属性进行处理,或者使用Volatile事件,使服务端丢弃原来的缓冲,只返回最新的数据(官网有该方法,在此就不描述)
  • 多路复用:Socket.io允许你在单个共享连接上创建多个namespace,这些namespace拥有单独的通信通道(room),也可设置单独的权限验证,但是可以共享原来的底层连接;例如,如果您想创建一个只有授权用户才能加入的管理员频道
  • 支持Room功能:room是在namespace下的,举个例子:namespace如同一片地区,room是这片地区中个房子,socket则是房子中的人,namespace是可以在别的namespace中通信的,但是room只能在该spacename下的room之间进行通信,socket也只能收到该namespace的广播

socket.io连接过程:

同样客户端发起http请求,并带有

Upgrade: websocket
Connection: Upgrade

服务端返回

"sid":"ab4507c4-d947-4deb-92e4-8a9e34a9f0b2"
"upgrades":["websocket"]
"pingInterval":25000
"pingTimeout":60000}
  • sid:sid 是本次会话的ID,因为一次连接包含了多个请求,sid 的作用就相当于 SESSION ID。也是客户端的标识
  • pingInterval:ping的间隔时长
  • pingTimeout:判断连接超时的时长

    当客户端收到响应之后,scoket.io会根据当前客户端环境是否支持Websocket。如果支持,则建立一个websocket连接,否则退回到长轮询进行双向数据通信。

engine.io协议原理

engine.io的数据分为Packet和Payload,其中 Packet是数据包,有6种类型:

0. open:从服务端发出,标识一个新的传输方式已经打开。

  1. close:请求关闭这条传输连接,但是它本身并不关闭这个连接。
  2. ping:客户端周期性发送ping,服务端响应pong。
  3. pong:服务端发送。
  4. message:真实数据
  5. upgrade:在转换(transport)前,engine.io会发送探测包测试新的transport(如websocket)是否可用,如果OK,则客户端会发送一个upgrade消息给服务端,服务端关闭老的transport然后切换到新的transport。用于升级协议
  6. noop:空操作数据包,客户端收到noop消息会将之前等待暂停的轮询暂停,用于在接收到一个新的websocket强制一个新的轮询周期。

4:总结

socket.io可以说是一个很好的工具,无论是用做聊天或者是其他实时的数据通信,在使用时也遇到过一些问题,后面都慢慢解决了

本文章如有错漏,欢迎指正。

轮询以及webSocket与socket.io原理的更多相关文章

  1. 你想了解的轮询、长轮询和websocket都在这里了

    日常生活中,有很多需要数据的实时更新,比如群聊信息的实时更新,还有投票系统的实时刷新等 实现的方式有很多种,比如轮询.长轮询.websocket 轮询 轮询是通过设置页面的刷新频率(设置多长时间自动刷 ...

  2. php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)

    php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...

  3. 即时通信WebSocket 和Socket.IO

    WebSocket HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯. 在2008年诞生,2011年成为国际标准. 现在基本所有浏览器都已经支持了. We ...

  4. AndroidAsync :异步Socket,http(client+server),websocket和socket.io的Android类库

    AndroidAsync是一个用于Android应用的异步Socket,http(client+server),websocket和socket.io的类库.基于NIO,没有线程.它使用java.ni ...

  5. tornado 10 长轮询和 websocket

    tornado 10 长轮询和 websocket 一.长轮询 #在网页,我们经常扫码登录,那么问题来了,前端是如何知道用户在手机上扫码登录的呢 这里就需要用到长轮询 #长轮询 #客户端能够不断地向服 ...

  6. websocket与socket.io

    什么是Websocket? Websocket是一个独立于http的实时通信协议,最初是在HTML5中被引用进来的,在HTML5规范中作为浏览器与服务器的核心通信技术被嵌入到浏览器中.WebSocke ...

  7. 对.Net WebSocket 和Socket的原理的思考

    今早上班路上接到了一个朋友的微信信息,问我对WebSocket 是否熟悉,一楞,印象之中没有用过这个类....来到公司后,得空问了一下度娘,原来这是一个随着HTML5推出的一种新协议,意义在于能实现浏 ...

  8. websocket 与Socket.IO介绍

    一  websocket WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如 Chrome,Safrie,Firefox,Opera,IE等等,对该协议支持最早的 ...

  9. Tornado长轮询和WebSocket

    Http协议是一种请求响应式协议, 不允许服务端主动向客户端发送信息. 短轮询是一种简单的实现服务端推送消息的解决方案, 客户端以一定间隔自动向服务端发送刷新请求, 服务端返回要推送的消息作为响应. ...

随机推荐

  1. 关于ECharts图表反复修改都无法显示的解决方案

    解决方案:清空浏览器所有记录,再次刷新即可

  2. IIS7 网站发布常见报错问题解决方案汇总

    本文实例为大家分享了IIS7 网站发布常见问题,以及五种问题的解决方法,供大家参考,具体内容如下: 1.不是有效的Win32位应用程序 : 解决方案: 1).进入应用程序池=>选中网站=> ...

  3. linux 查询文件命令

    jps; 当前服务器中所有的java进程: jps |grep XXX; 查询当前服务器某个进程: locate xxx;查询某个文件的位置:

  4. 用C语言实现井字棋(人人/AI人机)--完结版

    目录 用C语言实现井字棋(人人/AI人机)--完结版 BUG与优化3: 1. 修改了step的计算方法,每个玩家玩完就加一次step 2. 改变了电脑下棋的逻辑,每个玩家玩完之后都跳过这次循环 源码: ...

  5. 深入探究MinimalApi是如何在Swagger中展示的

    前言 之前看到技术群里有同学讨论说对于MinimalApi能接入到Swagger中感到很神奇,加上Swagger的数据本身是支持OpenApi2.0和OpenApi3.0使得swagger.json成 ...

  6. c++ 超长整数减法 高精度减法

    c++ 超长整数减法 高精度减法 实现思路 和加法类似,设置临时变量记录借位 当对应位数相减得到的结果大于等于0时,该位数字为本身值,否则需要加上借位的10.则\(t=(t+10)%10\) 打卡代码 ...

  7. 2.1 动为进程,静为程序 -进程概论 -《zobolの操作系统学习札记》

    2.1 动为进程,静为程序 -进程概论 目录 2.1 动为进程,静为程序 -进程概论 问1:发明进程的原因? 问2:现在计算机中的进程的定义是什么? 问3:为什么进程跟处理器的联系更密切? 问4:进程 ...

  8. UML之顺序图(时序图)

    1 顺序图 1.1 顺序图的概念 顺序图(sequence diagram): 用来描述为了完成确定事务,对象之间按照时间消息交互的顺序关系. 1.2 顺序图样式和元素 (1) 对象及命名 (2) 生 ...

  9. 全国降雨侵蚀力因子R值

      数据下载链接:百度云下载链接​ 降雨侵蚀力因子其实是反应降雨对土壤侵蚀的潜在能力,就是降雨的冲刷对土壤的侵蚀效应. 在过去几天查阅文献资料的过程中,本人亲眼看见过的关于因子R的计算方法就超过30种 ...

  10. 01. DOCKER - 容器技术

    什么是容器 对于容器这个词,大部分人第一时间想到的肯定是生活中常见瓶瓶罐罐,用来装水的东西.它给人的第一感觉就是能 "装". 而在 IT 领域,Container 就被直译为容器, ...