Websocket应用协议已经普及多年了,它是HTTP1.1的内部升级协议,主要作用是补充HTTP1.1无法灵活地主动推送消息给客户端的缺陷问题。在这里主要介绍一下使用组件如何扩展一个完整的Websocket协议。
协议介绍
Websocket并不复杂,但协议文档内容还是很全面的,以下是协议原文
https://tools.ietf.org/html/rfc6455。其实一个简单的图可以看出Websocket协议结构。
在这里主要介绍组件是如何实现的就不详细介绍内容了。
存储顺序
在协议中有一个地方需要关注存储顺序,那就是消息长度描述。不同语言平台对于基础值类型的存储顺序都不一样分别是:大端和小端。这个协议使用的是大端存储顺序,但.NET则是使用小端存储顺序;所以使用组件解Weboskcet协议前要更改一下流读写的存储顺序。
IServer.Options.LittleEndian = false;
组件可以通过配置来统一更改网络流针对大小端读写配置,应用中也可以默认用小端读出来后再移位转换也是可以。
分析状态
虽然Websocket已经有协议描述,但在分析过程中还是需要一些状态来处理。在TCP流中无法知道当前buffer里的情况,有可能不到一个消息帧,或存在多个消息帧;更有可能当前流的尾部可能只两个字节内容的playload len 127的情况;为了应对存在不同状态的网络流,在分析协议过程需要制定各种状态,以便于下一次网络数据到来直接跑到相关状态分配处理。
public enum DataPacketLoadStep{
//量开始状态 None, //分析完头部信息 Header, //分析完成内容长度信息 Length, //内容在校检状态 Mask, //分析完成 Completed}
握手处理
其实Websocket设计作为http 1.1的一个升级协议,所以在连接开始是通过http协议作为应用握手确认;确认后双方即可随意发送基于websocket协议描述的帧数据。
当服务端收到HTTP请求存在Upgrade头部信息的内容是Websocket的情况说明客户端要求升级到Websocket协议。
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket