我对WebSocket的了解与阐述。
它出现の背景
我们知道HTTP 1.0一个请求建立,就需要经历一次TCP连接,这样会导致三次握手和四次挥手的重复成本较多。
所以在HTTP 1.1的时候出现了keep-alive这个属性,它可以允许一次TCP连接进行多个HTTP请求的发送。但因此会有一些问题,客户端无法分辨具体的包是哪个请求的,所以这些包只能按照请求的顺序返回,因此就有了线头阻塞。同时他不支持服务端主动推送的能力。
HTTP 2.0新增了服务器主动推送的能力,同时它把请求进行了更细的拆分,使用了帧、流,每个请求是一个流,一个流可以分成很多帧,还带有标记号,解决了线头阻塞。
它的机制
WebSocket实质是借助HTTP协议来实现使用TCP去进行传输的协议。
第一步:客户端发送协议升级请求,HTTP请求上加上头
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: k1kbxGRqGIBD5Y/LdIFwGQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
2.101 协议升级
Connection: Upgrade
Sec-WebSocket-Accept: y73KZR4t+hqD6KKYbkx2tULfBsQ=
Upgrade: websocket
websocket连接所维持的时间是依赖tcp实现的。因为我们发现tcp层会一直发送探测包。达到阈值之后,连接就会被断开。所以我们想维持websocket连接的话,需要自己去发送心跳包,比如ping,pong。
TCP保活
why
很多防火墙对于空闲socket自动关闭。
对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制。
如果网络正常, socket也通过close操作来进行优雅的关闭, 那么一切完美. 可是有很多情况, 比如网线故障, 客户端一侧突然断电或者崩溃等等, 这些情况server并不能正常检测到连接的断开.
保活的方式
1)应用层面的心跳机制
客户端主动发送, 服务器接收后进行回应。
一是比较灵活.二是通用。
2)TCP协议自带的保活功能
打开keep-alive功能
减少了应用层代码的复杂度. 推测也会更节省流量, 因为一般来说应用层的数据传输到协议层时都会被加上额外的包头包尾. 由TCP协议提供的检活, 其发的探测包, 理论上实现的会更精妙
参考文章
https://blog.51cto.com/u_15147537/5983943
https://zhuanlan.zhihu.com/p/618891777