一、HTTP协议的弊端
将HTTP协议的主要弊端总结如下:
- (1) 半双工协议:可以在客户端和服务端2个方向上传输,但是不能同时传输。同一时刻,只能在一个方向上传输。
- (2) HTTP消息冗长:相比于其他二进制协议,有点繁琐。
(3) 针对服务器推送的黑客攻击,例如长时间轮询。
现在很多网站的消息推送都是使用轮询,即客户端每隔1S或者其他时间给服务器发送请求,然后服务器返回最新的数据给客户端。HTTP协议中的Header非常冗长,因此会占用很多的带宽和服务器资源。
比较新的技术是Comet,使用了AJAX。虽然可以双向通信,但是依然需要发送请求,而且在Comet中,普遍采用了长连接,也会大量消耗服务器的带宽和资源。
为了解决这个问题,HTML5定义的WebSocket协议。二、WebSocket协议介绍
在WebSocket API中,浏览器和服务器只需要一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道,两者就可以直接互相传送数据了。
WebSocket基于TCP双向全双工协议,即在同一时刻,即可以发送消息,也可以接收消息,相比于HTTP协议,是一个性能上的提升。
特点:单一的TCP连接,全双工;
- 对代理、防火墙和路由器透明;
- 无头部信息、Cookie和身份验证;
- 无安全开销;
- 通过”ping/pong”帧保持链路激活;
- 服务器可以主动传递消息给客户端,不再需要客户端轮询;
拥有以上特点的WebSocket就是为了取代轮询和Comet技术,使得客户端浏览器具备像C/S架构下桌面系统一样的实时能力。
浏览器通过js建立一个WebSocket的请求,连接建立后,客户端和服务器端可以通过TCP直接交换数据。
因为WebSocket本质上是一个TCP连接,稳定,所以在Comet和轮询比拥有性能优势,如图所示:
三、WebSocket连接
3.1 连接建立
client端发送握手请求,请求消息如图所示:
- 这个请求和普通的HTTP请求不同,包含了一些附加头信息,其中附加头信息”Upgrade: Websocket”表明这是一个申请协议升级的HTTP请求。
- 服务器尝试解析这个信息,然后返回应答信息给客户端,因此客户端和服务器端的WebSocket连接就建立起来了,双方可以通过这个连接通道自由的传递信息。
- 这个连接会持续到某一方主动断开连接。
服务端的应答请求如图所示:
client消息中的”Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造一个”SHA-1”的信息摘要,把”Sec-WebSocket-Key”加上一个魔幻字符串。使用”SHA-1”加密,然后进行BASE64编码,将结果作为”Sec-Webscoket-Accept”头的值。
3.2 生命周期
- 握手成功,连接建立后,以”Messages”的方式通信。
- 一个消息由一个或者多个”帧“组成。
- 帧都有自己的类型,同一消息的多个帧类型相同。
- 广义上,类型可以是文本、二进制、控制帧如信号。
3.3 连接关闭
- 安全方法是关闭底层TCP连接以及TLS会话。
- 底层的TCP连接,正常情况下,应该由服务器先关闭。
- 异常时(比如合理的时间内没有接收到服务器的TCP Close),可以由客户端发起TCP Close。因此,在client发起TCP Close时,服务器应该立即发起一个TCP Close操作;客户端则等待服务器的TCP Close;
- 关闭消息带有一个状态码和可选的关闭原因,它必须按照协议要求发送一个Close控制帧。