websocket是一种网络通信协议,是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议
基于http协议的长连接
在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加"Connection:keep-alive" header才能够支持,而HTTP1.1默认支持。
当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的TCP连接。但是Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。客户端和服务器都能选择随时关闭连接,头中设置"Connection:close"即可。
基于http协议的长连接减少了请求,减少了建立连接的时间,但是每次交互都是由客户端发起的,客户端发送消息,服务端才能返回客户端消息。
websocket
Websocket是应用层第七层上的一个应用层协议,它必须依赖 HTTP 协议进行一次握手 ,握手成功后,数据就直接从 TCP 通道传输,与 HTTP 无关了。即:websocket分为握手和数据传输阶段,即进行了HTTP握手 + 双工的TCP连接。
- 1.握手阶段
客户端发送消息
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Version: 13
- “Sec-WebSocket-Key”是一个Base64 encode的值,这个是浏览器随机生成
- “Sec_WebSocket-Protocol”是一个用户定义的字符串,用来区分同URL下,不同的服务所需要的协议
- “Sec-WebSocket-Version”是告诉服务器所使用的Websocket Draft(协议版本)
服务端返回消息
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
- “Sec-WebSocket-Accept”是经过服务器确认,并且加密过后的 Sec-WebSocket-Key,如果这个Sec-WebSocket-Accept计算错误浏览器会提示:Sec-WebSocket-Accept dismatch,如果返回成功,Websocket就会回调onopen事件
返回的状态码为101,表示同意客户端协议转换请求,并将它转换为websocket协议。以上过程都是利用http通信完成的,称之为websocket协议握手(websocket Protocol handshake),进过这握手之后,客户端和服务端就建立了websocket连接,以后的通信走的都是websocket协议。
- 2.传输阶段
Websocket的数据传输是frame形式传输的,比如会将一条消息分为几个frame,按照先后顺序传输出去。这样做会有几个好处:- a.大数据的传输可以分片传输,不用考虑到数据大小导致的长度标志位不足够的情况。
- b.和http的chunk一样,可以边生成数据边传递消息,即提高传输效率。
websocket具有以下几个方面的优势:
- (1)建立在 TCP 协议之上,服务器端的实现比较容易。 -(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。 -(3)数据格式比较轻量,性能开销小,通信高效。 -(4)可以发送文本,也可以发送二进制数据。 -(5)没有同源限制,客户端可以与任意服务器通信。 -(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。 -(7)Websocket解决了HTTP的被动性问题,可以由服务端主动推送消息给客户端。
缺点
websocket 是长连接,受网络限制比较大,需要处理好重连,比如用户进电梯或电信用户打个电话网断了,这时候就需要重连,如果 ws 一直重连不上,有些较复杂的业务方会不愿意的,是不是还要搞个 http 降级?所以大部分不重要的业务,使用 ws 不如使用 http 轮训来的简单、实在。
注意:本文归作者所有,转载请标明出处 http://blog.appcnd.com/post/article408a03d2a0a1002d