websocket原理
简介:websocket是h5提供j的一种在单个tcp连接上进行的全双工双向传输的协议,最主要支持服务端主动向客户端推送消息,期间只需一次握手即可。
在websocket未诞生之前,由于http短连接,无状态的特行,一般实时通话常用的技术是长连接和ajax轮询
ajax轮询原理:浏览器每隔几秒发送一个请求,询问服务器是否有新消息。
-
客户端:是否有新消息?request
-
服务端:没有 response
-
客户端:是否有新消息 reques
-
服务端:有了,给你 response
-
…
长连接原理:和ajax轮询相似,但是是阻塞式长连接,请求发给服务器后,若没有新消息则这个连接不中断,服务端不返回response,客户端一直借不到请求,则这个请求阻塞在收请求,等有新消息后服务端返回新消息给客户端,客户端再进行依次轮询。
- 客户端:有新消息吗 ,没有就等有再发给我 request
- 服务端:…sleep(),,,
- 服务端:有新消息–>发送给客户端 response
- 客户端:有新消息吗 ,没有就等有再发给我 request
ajax轮询和长连接都是不断的建立http连接,等待服务端处理,则体现了http的另一特性:被动
特点:ajax轮询和长连接都消耗资源较大,ajax轮询 需要服务器有很快的处理速度和资源(速度),长连接需要有很高的并发,也就是说同时接待客户的能力(场地大小),所以ajax轮询 和长连接 都有可能发生客户端请求服务端是服务端返回503错误(网站超过了系统资源限制造成的,主要是程序占用资源太多).
websocket实现:websocket是持久化协议,websocket基于http,或者简而言之是借用http来完成一部分握手,协议中,upgrade:websocket connection:upgrade告诉服务器发起的是一个websocket协议
- Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== base64.encode之后的值,浏览器随笔生成,用来验证是否为websocket助理
Sec-WebSocket-Protocol: chat, superchat 用户自己定义的字符串,用来区分同url下,不同服务需要用到的协议(我要服务于谁的意思)
Sec-WebSocket-Version: 13 协议版本,先再统一使用13版本
websocket协议 ---->>>客户端发送请求
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
服务端回复-------->>>成功建立连接
HTTP/1.1 101 Switching Protocols
Upgrade: websocket 表明现在已是websocket协议
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= 经过服务器将客户端传会的webocket-key加密,用来验证真伪
Sec-WebSocket-Protocol: chat 最终使用的协议
- 客户端:升级建立websocket协议连接 request
- 服务端:已经升级为websocket协议连接 response
- 客户端:有新消息回推消息 request
- 服务端:新消息--------->>>客户端
- 服务端:新消息--------->>>客户端
只需经过一次http请求就建立持久连接。
websocket为什么他会解决服务器上消耗资源的问题呢?
我们所用的程序是要经过两层代理,首先是服务器通过接收到的请求进行解析后来转交给应用程序处理后来返回数据给客户端。
服务器相当于接线员,程序相当于客服,接线员速度很快,来多少个人都能准确地将电话转接给客服,但是客服处理速度很慢。导致响应速度很慢。
而websocket相当于,有信息的时候客服将信息交给接线员,接线员再统一交给用户。这样就解决客户处理速度慢的情况。
同时,传统http连接法,http时短连接且无状态,需要不停的建立连接关闭连接,无状态每次都需要告诉服务器你是谁,会造成转接到客服的效率下降,同时有客户端主动询问转变为服务器有消息就推送。
缺陷:websocket在发送消息中通过网络链路中各个节点转发到目的地是一个跨越千山万水的过程,很容易在中间某个节点出现问题,可能长时间不发送消息中间节点会自主断开连接,而计算机网络协议栈的实现中又会有一层套一层的缓存,除非填满这些缓存,程序根本不会发现任何错误,这样虽然服务器在给客户端一直发送消息但是客户端时一直接收不到的。
解决方案:让服务器和客户端能够发送 Ping/Pong Frame。这种 Frame 是一种特殊的数据包,它只包含一些元数据而不需要真正的 Data Payload,可以在不影响 Application 的情况下维持住中间网络的连接状态。