websocket协议
一、轮询技术和HTTP流技术
现在,很多网站为了实现推送技术,所用的技术都是轮询。
轮询是指在特定的时间间隔(如每一秒),由浏览器对服务器发起HTTP请求,然后由服务器返回数据给浏览器。由于HTTP协议是惰性的,只有客户端发起请求,服务器才会返回数据。
轮询技术实现的前提条件同样是基于这种机制。而WebSocket属于服务端推送技术,本质是一种基于TCP的应用层协议,可以实现持久连接的全双工双向通信。
而在websocket协议之前,我们得知道轮询技术和HTTP流技术。
1 Ajax短轮询
Ajax短轮询即客户端周期性的向服务器发起HTTP请求,不管服务器是否真正获取到数据,都会向客户端返回响应。每个 request 对应一个 response ,由于HTTP/1.1的持久连接(建立一次TCP连接,发送多个请求)和管线化技术(异步发送请求),使得HTTP请求可以在建立一次TCP连接之后发起多个异步请求。
2 Ajax长轮询
Ajax长轮询本身不是一个真正的推送,而是短轮询的一种变体。
在客户端向服务器发起HTTP请求之后,服务器并不是每次都立即响应,当服务器得到最新数据时,会向客户端传输数据;当数据没有更新时,服务器会保持这个连接,等待更新数据之后,才向客户端传输数据。
若服务端长时间没有更新,一段时间后连接就会超时,而客户端收到超时信息后,会重新发出HTTP请求给服务器。
Ajax长轮询中服务器只有获取到更新的数据之后才会给客户端传输数据。而虽然服务端可以主动向客户端传输数据,依然需要反复发出请求,其中的HTTP请求也比短轮询少了很多。
二、websocket
应用层协议。
HTTP协议是单向通信协议,只有客户端发起HTTP请求,服务端才会返回数据。而websocket协议是双向通信协议,在建立连接之后,客户端和服务器都可以主动向对方发送或接收数据。
websocket协议建立的前提需借助HTTP协议,建立连接之后,持久连接的双向通信就与HTTP协议无关了。
websocket协议的目标是在一个独立的持久连接上提供全双工双向通信。客户端和服务器可以向对方主动发送和接受数据。在JS中创建websocket后,会有一个HTTP请求发向浏览器以发起请求。在取得服务器响应后,建立的连接会使用HTTP升级将HTTP协议转换为websocket协议。所以,只有使用标准的HTTP协议无法实现websocket,只有支持那些协议的专门浏览器才能正常工作。
由于websocket使用了自定义协议,所以URL与HTTP协议略有不同。未加密的连接为ws://
,加密的连接为wss://
。
协议升级格式:
Connection
:Connection必须设置为Upgrade,表示客户端希望连接升级Upgrade
:Upgrade必须设置为websocket,表示在取得服务器响应之后,使用HTTP,升级将HTTP协议转换(升级)为websocket协议。Sec-WebSocket-key
:随机字符串,用于验证协议是否为websocket协议而非HTTP协议Sec-WebSocket-Version
:表示使用websocket的哪一个版本Sec-WebSocket-Accept
:根据Sec-WebSocket-Accept和特殊字符串计算,验证协议是否为websocket协议Sec-WebSocket-Location
:与Host字段对应,表示请求websocket协议的地址HTTP/1.1 101 Switching Protocols
:101状态码表示升级协议,在返回101状态码后,HTTP协议完成工作,转换为websocket协议此时就可以进行全双工双向通信了
为了建立⼀个WebSocket连接,客户端浏览器首先要向服务器发起⼀个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息,通过这个附加头信息完成握手过程并升级协议的过程。
1 协议格式
- FIN:一个消息有可能由一个或多个帧组成,FIN字段为1表示末尾帧。
- RSV1~3:保留字段
只在扩展时使用,若未启用扩展则应置1,若收到不全为0的数据帧,且未协商扩展则立即终止连接。- pocode:标志当前数据帧类型
0x0:表示这是个延续帧,当opcode为0表示本次数据传输采用了数据分片,当前收到的帧为其中一个分片
0x1:表示文本帧
0x2:表示二进制帧
0x3-0x7:保留,暂未使用
0x8:表示连接断开
0x9:表示ping帧
0xa:表示pong帧
0xb-0xf:保留,暂未使用- Payload长度:存放真正想要传输数据的长度,单位为字节
- Payload数据:真正要传输的数据
起始TCP协议本身就是全双工,但若直接使用纯TCP进行传输数据,就会有粘包的问题出现。
而为了解决这个问题,上层协议一般会用消息头+消息体
的格式去重新包装要发的数据,消息头里一般含有消息体的长度,通过这个长度就可以去截取真正的消息体。
HTTP协议和大部分RPC协议和websocket协议都会如此来设计。
总结
websocket继承了tcp的全双工能力,且提供了解决粘包方案,适用于服务器和客户端大量频繁交互的大量场景,如网页或小程序游戏,网页聊天室等。