websocket的握手及消息帧

websocket是基于应用层的传输控制协议,而socket是基于传输层的传输控制协议。它们都是全双工的(可以同时接收和发送),传输层意味着数据都是以16进制传输,而传输层以二进制传输。

websocket的握手分为客户端请求和服务器端回应。

客户端的请求如下:

GET / HTTP/1.1       // 这个请求必须是GET请求,并且HTTP的协议必须是1.1
Connection:Upgrade   // 表示客户端希望连接升级
Upgrade:websocket   // 这个值必须是websocket,表示请求升级为websocket协议
Host:xxxx           // 请求的主机名称
Origin:xxxx         // 打开这个socket的页面
Sec-Websocket-Key:sN9cRrP/n9NdMgdcy2VJFQ== // 随机生成的字符串,客户端通过GUID来验证这个参数是不是一个有效请求
Sec-WebSocket-Version:13  // websocket使用的协议,RFC6455规定这个值必须万为13
Sec-WebSocket-Protocol:xxx // 客户端可以指定应用程序支持的协议,服务器选择其中的一个做为双方通信的协议
Sec-webSocket-Extension:xxxx // 客户端指定某些扩展协议,服务器选择其中一个

服务器端的回应如下:

HTTP/1.1 101 Switching Protocols // 服务器端同意客户端的握手请求
Connection: Upgrade // 同意这个连接升级
Sec-WebSocket-Accept: IIRiohCjop4iJrmvySrFcwcXpHo= // 通过GUID计算出来的值
Sec-WebSocket-Version: 13 // websocket的版本
Upgrade: websocket // 同意升级为websocket协议

如果HTTP的状态不是101客户端应该断开这个连接,如果Sec-WebSocket-Protocol规定了其中的子协议则服务器必须响应其中一个,否则客户端必须断开这个连接。

Sec-WebSocket-Accept的值以php计算如下:

$client_key = 'xxxxx';
$guid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$join = $client_key . $guid;
$sha1 = sha1($join,true);
$accept = base64_encode($sha1);

也就是客户端的Sec-WebSocket-Key的值加上GUID后,哈希为20个字符串后,再使用base64编码即可得到服务器的Sec-WebSocket-Accept的值

数据帧格式:(这个图示转载别人的,原帖在这里:https://www.cnblogs.com/songwenjie/p/8575579.html)

第一个字节包括:

FIN:一位,是否是最后一个消息分片。如果此值是0表示这个消息不是最后一个,反之就是最后一个

RSV1,RSV2,RS3:三位,用于扩展定义的值各一位,如果没有扩展这个值必须为0

opcode:四位,消息接收类型

第二个字节:

MASK:一位,数据是否经过掩码处理,客户端发往服务端的数据都必须经过掩码处理,值为1。

payloadData的长度:7位,7+16位,7+64位
如果其值在0-125,则是payload的真实长度。
如果值是126,则后面2个字节形成的16位无符号整型数的值是payload的真实长度。
如果值是127,则后面8个字节形成的64位无符号整型数的值是payload的真实长度。

其中《原来你是这样的websocket》对消息帧讲解的非常透彻,文中一些图片和文字均来自这篇文章。

这个里有几个不错的帖子

https://www.cnblogs.com/songwenjie/p/8575579.html(原来你是这样的websocket)

https://segmentfault.com/a/1190000013298527(websocket协议)

https://blog.csdn.net/stoneson/article/details/8063802(websocket规范 RFC6455翻译中文文档)

https://www.w3.org/TR/websockets/(w3c关于websocket介绍)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值