注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

itoedr的it学苑

记录从IT文盲学到专家的历程

 
 
 

日志

 
 

websocket的原理与应用思考  

2015-03-05 09:42:00|  分类: web远程管理工具 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

        websocket是一种协议,一种服务器端进程与客户端进程进行通讯的协议,本质上和http,tcp一样。协议是用来说明数据是如何传输的。它的url前缀是ws:// 或者wss://,后者是加密的websocket。它的url诸如这样:ws://10.16.15.64:3201/,与http协议的展现形式类似。

        客户端和服务端进行websocket交互的方式也有人理解为“HTTP握手+TCP数据传输”的方式。

HTTP握手+TCP数据传输

握手和传输的整个流程简析:

1)浏览器(支持Websocket的浏览器)像HTTP一样,发起一个请求,然后等待服务端的响应;

2)服务器返回握手响应,告诉浏览器请将后续的数据按照websocket制定的数据格式传过来;

3)浏览器和服务器的socket连接不中断,此时这个连接和http不同的是它是双工的了;

4)浏览器和服务器有任何需要传递的数据的时候使用这个长连接进行数据传递;

       这里说它是HTTP握手,是因为浏览器和服务器在建立长连接的握手过程是按照HTTP1.1的协议发送的,有Request,Request Header, Response, Response Header。但是不同的是Header里面的字段是有特定含义的。

        说它是TCP传输,主要体现在建立长连接后,浏览器是可以给服务器发送数据,服务器也可以给浏览器发送请求的。当然它的数据格式并不是自己定义的,是在要传输的数据外层有ws协议规定的外层包的。

握手过程说明

websocket的原理与应用思考 - itoedr - itoedr的it学苑
 

图:一个握手过程

         Upgrade头表示的意思是“客户端除了http之外也支持websocket协议,而且更倾向使用websocket,服务端如果支持的话,咱们就换websocket协议吧”

         sec-websocket-version:是指出浏览器支持的websocket号。这里是支持hybi-13。这里是不会出现9-12的版本号的。websocket协议规定9-12是保留字段。

         sec-websocket-key:算是一种验证返回回来的服务端是否是支持websocket的验证算法。与Response中的sec-websocket-accept是对应的。

        sec-websocket-accept与sec-websocket-key的对应算法是:

        sec-websocket-accept = base64(hsa1(sec-websocket-key + 258EAFA5-E914-47DA-95CA-C5AB0DC85B11))

如果返回的sec-websocket-accept不对,在chrome下会出现Sec-WebSocket-Accept dismatch的错误。

          Response返回的HTTP Staus是101,代表服务端说“我们双方后面就按照websocket协议来进行数据传输吧”

数据传输过程

          websocket的数据传输是frame形式传输的,比如会将一条消息分为几个frame,按照先后顺序传输出去。这样做会有几个好处:

1) 大数据的传输可以分片传输,不用考虑到数据大小导致的长度标志位不足够的情况。

2) 和http的chunk一样,可以边生成数据边传递消息,即提高传输效率。

传输协议:

websocket的原理与应用思考 - itoedr - itoedr的it学苑
 

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位,任意的应用数据,放在扩展数据之后,应用数据的长度=负载数据的长度-扩展数据的长度

读取数据需要按照这个格式读取,发送数据也需要按照这个格式发送返回。

代码示例:

http://www.cnblogs.com/yjf512/archive/2013/02/18/2915171.html

应用:

1 chatofPemelo

聊天室

https://github.com/NetEase/chatofpomelo

2 osxair

远程控制air

https://github.com/jianfengye/MyWorks/tree/master/osxair

  评论这张
 
阅读(100)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017