传统的HTTP连接是这样的
HTTP1.0
每发一个请求都要先建立一个TCP连接,客户端收到响应后连接断开,发起第二次请求时重新建立新的TCP连接。这就好比你和女朋友打电话,拨通电话后,你说一句,女朋友回复完后双方就自动挂机了。你要讲第二句,不好意思,你得重新拨号,如此往复,最后你可能疯掉了。
但早期HTTP1.0就是这样,打开一个网页如果有100个请求,那就要建立100次连接,这种方式对资源是一种严重的浪费。
HTTP1.1
到了HTTP1.1 有了一定改善,出了一个叫长连接的模型(Keepalive),也叫持久连接。发送请求前,先建立TCP连接,不过,连接后,你可以多次发送请求和接受响应了,效率大幅提升。
但是,HTTP 请求是按顺序发出的,第二次请求必须在第一个响应达到后才能发起。就好比,你和女朋友打电话时,拨通后,你说一句,等她回复后才能接着说第二句,如果她还没回你,那对不起,你只能等。 这样处理也是有好处的,我明确知道你回复我的是哪句话。
HTTP1.1已经比HTTP1.0先进了很多,虽然HTTP1.1 还有个管道连接(Pipelining),就是建立连接后,可以不用等上一个请求的响应结果就可以发送第二个请求。
但这个功能在浏览器中默认是关闭的。主要原因有:
- 一些代理服务器不能正确的处理 HTTP Pipelining。
- Head-of-line Blocking 连接头阻塞:在建立起一个 TCP 连接之后,假设客户端在这个连接连续向服务器发送了几个请求。按照标准,服务器应该按照收到请求的顺序返回结果,假设服务器在处理首个请求时花费了大量时间,那么后面所有的请求都需要等着首个请求结束才能响应。
不过,这些问题在HTTP2.0中得到了解决,关于2.0 这个可以后续再展开讲
传统的HTTP服务都是由客服端向服务器主动发起请求获取结果,客户端不主动就永远拿不到结果,所以对实时性要求比较的场景,我们一般用轮询的方式,每隔一段时间去问一下服务器,
服务器有新的数据了吗?
没有
过了几秒钟,又问
服务器有新的数据了吗?
有了,我给你
就这样如此往复的执行。
那对即时性要求更高的场景,有没有可能服务器主动告知客户端,只要有数据更新了就通知客户端,而不是让客户端去询问呢,答案就是WebSocket
WebSocket
WebSocket是一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 是独立的、创建在 TCP 上的协议,和 HTTP 的唯一关联是使用 HTTP 协议的101状态码进行协议切换,使用的 TCP 端口是80,可以用于绕过大多数防火墙的限制。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端直接向客户端推送数据而不需要客户端进行请求,在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并允许数据进行双向传送。
WebSocket常出现在线聊天室、在线客服系统、评论系统、WebIM等业务场景中。
WebSocket 作为一种规范,在实际开发过程中,我们只要按照规范来构建服务端和客户端就可以基于WebSocket实现Web上的即时聊天功能。好在,现在并不需要我们从零去自己实现WebSocket协议,Socket.IO 就是一个开源的WebSocket库。
今天这篇文章就先写到这里,下一期基于 websocket 实战一把。
关注公众号「Python之禅」,回复「1024」免费获取Python资源