TCPIP,WebSocket和MQTT
按照OSI⽹络分层模型,IP是⽹络层协议,TCP是传输层协议,⽽HTTP和MQTT是应⽤层的协议。在这三者之间, TCP是HTTP和MQTT底层的协议。⼤家对HTTP很熟悉,这⾥简要介绍下MQTT。MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的⼀个即时通讯协议,有可能成为物联⽹的重要组成部分。该协议⽀持所有平台,⼏乎可以把所有联⽹物品和外部连接起来,被⽤来当做传感器的通信协议。
1. HTTP的不⾜
HTTP协议经过多年的使⽤,发现了⼀些不⾜,主要是性能⽅⾯的,包括:
HTTP的连接问题,HTTP客户端和服务器之间的交互是采⽤请求/应答模式,在客户端请求时,会建⽴⼀个HTTP连接,然后发送请求消息,服务端给出应答消息,然后连接就关闭了。(后来的HTTP1.1⽀持持久连接)
因为TCP连接的建⽴过程是有开销的,如果使⽤了SSL/TLS开销就更⼤。
在浏览器⾥,⼀个⽹页包含许多资源,包括HTML,CSS,JavaScript,图⽚等等,这样在加载⼀个⽹页时要同时打开连接到同⼀服务器的多个连接。
HTTP消息头问题,现在的客户端会发送⼤量的HTTP消息头,由于⼀个⽹页可能需要50-100个请求,就会有相当⼤的消息头的数据量。
HTTP通信⽅式问题,HTTP的请求/应答⽅式的会话都是客户端发起的,缺乏服务器通知客户端的机制,在需要通知的场景,如聊天室,游戏,客户端应⽤需要不断地轮询服务器。
⽽ WebSocket是从不同的⾓度来解决这些不⾜中的⼀部分。还有其他技术也在针对这些不⾜提出改进。
2. WebSocket
WebSocket则提供使⽤⼀个TCP连接进⾏双向通讯的机制,包括⽹络协议和API,以取代⽹页和服务器采⽤HTTP轮询进⾏双向通讯的机制。
本质上来说,WebSocket是不限于HTTP协议的,但是由于现存⼤量的HTTP基础设施,代理,过滤,⾝份认证等等,WebSocket借⽤HTTP和HTTPS的端⼝。由于使⽤HTTP的端⼝,因此TCP连接建⽴后的握⼿消息是基于HTTP的,由服务器判断这是⼀个HTTP协议,还是WebSocket协议。 WebSocket连接除了建⽴和关闭时的握⼿,数据传输和HTTP没丁点关系了。
历时11年,WebSocket终于被批准成为IETF的建议标准:RFC6455.其前⾝是WHATWG (Web Hypertext Application Technology Working Group)的⼯作。⽽Web Socket的API,是W3C的⼯作。
WebSocket可以只打开⼀个到的链接,并且在此链接上信息。其优势在于减少了传统⽅法的复杂性,提⾼了可靠性和降低了浏览器和客户端之间的负载。这样做的⼀个重要原因是,很多屏蔽80以外的端⼝,迫使越来越多的应⽤迁移到HTTP上来了。
11年的websocket草案的变迁中,有的浏览器⽀持的是旧版本的websocket,⽐如iPhone4上的safari使⽤的WebSocket是旧版的握⼿协议,那么就要使⽤就的握⼿协议来制做服务器端。如今只有Safari⽀持旧版本的协议,Chrome和Firefox最新版都已升级⾄Hybi-10()。因此,我们再来看⼀下WebSocket新版协议Hybi-10。这次协议变更⾮常⼤,主要集中在握⼿协议和数据传输的格式上。
握⼿协议
我们先来看⼀下⼤致的区别:
1. 最⽼的websocket草案标准中是没有安全key,草案7.5、7.6中有两个安全key,⽽现在的草案10中只有⼀个安全key,即将 7.5、7.6中http头中
的"Sec-WebSocket-Key1″与"Sec-WebSocket-Key2″合并为了⼀个"Sec- WebSocket-Key"
2. 把http头中Upgrade的值由"WebSocket"修改为了"websocket";http头中的"-Origin"修改为了"Sec-WebSocket-Origin";
3. 增加了http头"Sec-WebSocket-Accept",⽤来返回原来草案7.5、7.6服务器返回给客户端的握⼿验证,原来是以内容的形式返回,现在是放到
了http头中;另外服务器返回客户端的验证⽅式也有变化。
websocket和socket
服务器⽣成验证的⽅式变化较⼤,我们来做⼀介绍。
旧版:
1
2
3
4
5//127.0.0.1:8000
6
7
8
9
旧版⽣成Token的⽅法如下:
取出Sec-WebSocket-Key1中的所有数字字符形成⼀个数值,这⾥是1427964708,然后除以Key1中的空格数⽬,得到⼀个数值,保留该数值整数位,得到数值N1;对Sec-WebSocket-Key2采取同样的算法,得到第⼆个整数N2;把N1和N2按照Big- Endian字符序列连接起来,然后再与另外⼀个Key3连接,得到⼀个原始序列ser_key。Key3是指在握⼿请求最后,有⼀个8字节的奇怪的字符串";">#",这个就是Key3。然后对ser_key进⾏⼀次md5运算得出⼀个16字节长的digest,这就是⽼版本协议需要的token,然后将这个token附在握⼿消息的最后发送回Client,即可完成握⼿。
新版:
1
2
3
4
5//127.0.0.1:8000
6
7
8
新版⽣成Token的⽅法如下:
⾸先服务器将key(长度24)截取出来,如4tAjitqO9So2Wu8lkrsq3w==,⽤它和⾃定义的⼀个字符串(长度 36)258EAFA5-E914-47DA-95CA-C5AB0DC85B11连接起来,然后把这⼀字符串进⾏SHA-1算法加密,得到长度为20字节的⼆进制数据,再将这些数据经过Base64编码,最终得到服务端的密钥,也就是ser_key。服务器将ser_key附在返回值Sec- WebSocket-Accept后,⾄此握⼿成功。
WebSocket也有⾃⼰⼀套帧协议。数据报⽂格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18      0                  1                  2                  3
01234567890123456789012345678901
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R|opcode|M|Payload len|    Extended payload length    |    |I|S|S|S|  (4)  |A|    (7)    |            (16/63)          |
|N|V|V|V|      |S|            |  (ifpayload len==126/127)  |
||1|2|3|      |K|            |                              |
+-+-+-+-+-------+-+-------------+---------------+
|    Extended payload length continued,ifpayload len==127  |    +---------------+-------------------------------+
|                              |Masking-key,ifMASK set to1  |
+-------------------------------+-------------------------------+
|Masking-key(continued)      |          Payload Data        |
+-----------------------------------------------+
:                    Payload                 :
+-------------------------------+
|                    Payload                 |
+---------------------------------------------------------------+
FIN:1位,⽤来表明这是⼀个消息的最后的消息⽚断,当然第⼀个消息⽚断也可能是最后的⼀个消息⽚断;
RSV1, RSV2, RSV3: 分别都是1位,如果双⽅之间没有约定⾃定义协议,那么这⼏位的值都必须为0,否则必须断掉WebSocket连接;Opcode:4位操作码,定义有效负载数据,如果收到了⼀个未知的操作码,连接也必须断掉,以下是定义的操作码:
%x0 表⽰连续消息⽚断
%x1 表⽰⽂本消息⽚断
%x2 表未⼆进制消息⽚断
%x3-7 为将来的⾮控制消息⽚断保留的操作码
%x8 表⽰连接关闭
%x9 表⽰⼼跳检查的ping
%xA 表⽰⼼跳检查的pong
%xB-F 为将来的控制消息⽚断的保留操作码
Mask:1位,定义传输的数据是否有加掩码,如果设置为1,掩码键必须放在masking-key区域,客户端发送给服务端的所有消息,此位的值都是1;
Payload length: 传输数据的长度,以字节的形式表⽰:7位、7+16位、或者7+64位。如果这个值以字节表⽰是0-125这个范围,那这个值就表⽰传输数据的长度;如果这个值是126,则随后的两个字节表⽰的是⼀个16进制⽆符号数,⽤来表⽰传输数据的长度;如果这个值是127,则随后的是8个字节表⽰的⼀个64位⽆符合数,这个数⽤来表⽰传输数据的长度。多字节长度的数量是以⽹络字节的顺序表⽰。负载数据的长度为扩展数据及应⽤数据之和,扩展数据的长度可能为0,因⽽此时负载数据的长度就为应⽤数据的长度。
Masking-key:0或4个字节,客户端发送给服务端的数据,都是通过内嵌的⼀个32位值作为掩码的;掩码键只有在掩码位设置为1的时候存在。
Payload data:  (x+y)位,负载数据为扩展数据及应⽤数据长度之和。
Extension data:x位,如果客户端与服务端之间没有特殊约定,那么扩展数据的长度始终为0,任何的扩展都必须指定扩展数据的长度,或者长度的计算⽅式,以及在握⼿时如何确定正确的握⼿⽅式。如果存在扩展数据,则扩展数据就会包括在负载数据的长度之内。
Application data:y位,任意的应⽤数据,放在扩展数据之后,应⽤数据的长度=负载数据的长度-扩展数据的长度。
三、 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适⽤于受限环境。例如,但不仅限于此:
⽹络代价昂贵,带宽低、不可靠。
在嵌⼊设备中运⾏,处理器和内存资源有限。
该协议的特点有:
使⽤发布/订阅消息模式,提供⼀对多的消息发布,解除应⽤程序耦合。
对负载内容屏蔽的消息传输。
使⽤ TCP/IP 提供⽹络连接。
有三种消息发布服务质量:
"⾄多⼀次",消息发布完全依赖底层 TCP/IP ⽹络。会发⽣消息丢失或重复。这⼀级别可⽤于如下情况,环境传感器数据,丢失⼀次读记录⽆所谓,因为不久后还会有第⼆次发送。
"⾄少⼀次",确保消息到达,但消息重复可能会发⽣。
"只有⼀次",确保消息到达⼀次。这⼀级别可⽤于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
⼩型传输,开销很⼩(固定长度的头部是 2 字节),协议交换最⼩化,以降低⽹络流量。
使⽤ Last Will 和 Testament 特性通知有关各⽅客户端异常中断的机制。
早在1999年,IBM的Andy Stanford-Clark博⼠以及Arcom公司ArlenNipper博⼠发明了MQTT(Message
Queuing Telemetry Transport,消息队列遥测传输)技术。BM和St. Jude医疗中⼼通过MQTT开发了⼀套Merlin系统,该系统使⽤了⽤于家庭保健的传感器。St. Jude医疗中⼼设计了⼀个叫做Merlin@home的⼼脏装置,这种⽆限发射器可以⽤来监控那些已经植⼊复律-除颤器和起搏器(两者都是基本的传感器)的⼼脏病⼈。
该产品利⽤MQTT把病⼈的即时更新信息传给医⽣/医院,然后医院进⾏保存。这样的话,病⼈就不⽤亲⾃去医院检查⼼脏仪器了,医⽣可以随时查看病⼈的数据,给出建议,病⼈在家⾥就可以⾃⾏检查。
IBM称该发射器包括⼀个⼤型触摸屏,⼀个嵌⼊式键盘平台,以及⼀个Linux操作系统。
在未来⼏年,MQTT的应⽤会越来越⼴,值得关注。
通过MQTT协议,⽬前已经扩展出了数⼗个MQTT服务器端程序,可以通过PHP,JAVA,Python,C,C#等系统语⾔来向MQTT发送相关消息。
此外,国内很多企业都⼴泛使⽤MQTT作为Android⼿机客户端与服务器端推送消息的协议。其中Sohu,Cmstop⼿机客户端中均有使⽤到MQTT作为消息推送消息。据Cmstop主要负责消息推送的⾼级研发⼯程师李⽂凯称,随着移动互联⽹的发展,MQTT由于开放源代码,耗电量⼩等特点,将会在移动消息推送领域会有更多的贡献,在物联⽹领域,传感器与服务器的通信,信息的收集,MQTT都可以作为考虑的⽅案之⼀。在未来MQTT会进⼊到我们⽣活的各各⽅⾯。
如果需要下载MQTT服务器端,可以直接去MQTT官⽅⽹站点击software进⾏下载MQTT协议衍⽣出来的各个不同版本。
MQTT和TCP、WebSocket的关系可以⽤下图⼀⽬了然:
MQTT协议专注于⽹络、资源受限环境,建⽴之初不曾考虑WEB环境。HTML5 Websocket是建⽴在TCP基础上的双通道通信,和TCP通信⽅式很类似,适⽤于WEB浏览器环境。虽然MQTT基因层⾯选择了TCP作为通信通道,但我们添加个编解码⽅式,MQTT over Websocket 也可以的。这样做的好处,MQTT的使⽤范畴被扩展到HTML5、桌⾯端浏览器、移动端WebApp、Hybrid等,多了⼀些想像空间。这样看来,⽆论是移动端,还是WEB端,MQTT都会有⾃⼰的使⽤空间。
MQ 遥测传输 (MQTT) V3.1 协议规范基于WebSocket 的MQTT 移动推送⽅案

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论