随着Web
领域的飞速发展,最初设计得十分简单的HTTP
协议在当今的应用上显得捉襟见肘,协议的瓶颈也逐渐显露出来。web
“既然HTTP
这么烂?为何咱们不抛弃它再设计一个全新的协议,而是要给他打补丁呢?”这是某次我和我舍友在宿舍喝着小酒,探讨SpringMVC
时谈到的一个话题。spring
最初的HTTP
,只是想把HTTP
看成传输HTML
文档的协议,设计者没有想到HTTP
经久不衰,须要承受愈来愈复杂的业务职责。浏览器
因此HTTP
的设计无可厚非,只是它不“那么地”适应这个时代了。可是目前基于HTTP
协议实现的Web
浏览器遍及全球,并不能随意动摇HTTP
的地位。服务器
因此为了知足现代社会日益增加的业务需求,涌现出无数企图“消除”HTTP
瓶颈的解决方案,其中的一项就是——“WebSocket
”。微信
为何会出现WebSocket
协议呢?websocket
假设咱们去实现相似微信同样的网页在线聊天工具,咱们要解决什么问题呢?网络
很显然,消息推送是当前业务场景下的一个技术瓶颈。异步
当前帐号收到了消息,咱们怎么在网页里“实时地”获取到消息并显示呢?注意要保障在线聊天的实时性。socket
能实现吗?显然不能。spring-boot
浏览器向客户端发起HTTP
请求,请求到含有当前消息的HTML
文件,渲染给用户。请求结束,不考虑持久链接的状况下,断开TCP
链接。
当服务器有新消息时,除非用户当前网页刷新,不然在只使用HTTP
的状况下没法实现实时性。
Ajax
意思就是用JavaScript
执行异步网络请求。
——《廖雪峰的JavaScript
教程》
使用Ajax
,能够在浏览器内用JavaScript
“偷偷”地发起网络请求,查询最新的消息,下降操做成本,提高用户体验。
为了保证明时性,须要前台定时发送Ajax
请求。例如:每5s
发送一次网络请求查询消息,将数据的延时性保持在固定间隔之内。
缺点很明显,会产生大量的HTTP
请求,若是消息长时间没有更新,十分浪费通讯资源。
为了不产生大量无用的HTTP
请求,产生了Comet
。
Ajax
发起查询消息的请求,服务器接收到该消息,不会当即响应,Comet
会将响应置于挂起状态,当服务器端有内容更新时,再返回响应。
与方案二相比,减小了无用的HTTP
请求,同时也保证了数据的实时性。
缺点就是服务器压力过大,服务器为了保持挂起的HTTP
响应,会消耗更多的宝贵的服务器资源。
由于HTTP
是请求响应模式,因此若是是基于HTTP
实现实时性,过于复杂。请求都是客户端发起的,客户端怎么知道服务器的内容何时更新呢?
因此,2011年12月11日
,RFC 6455 - The WebSocket Protocol
标准被确立。
WebSocket
,一样基于TCP
协议,是Web
浏览器与Web
服务器之间的全双工通讯标准。
若是有数据更新,服务器能够向客户端发送数据,使实现实时性变得简单。
WebSocket
链接的创建须要握手,说是握手,其实也是为了兼容HTTP
浏览器的一种手段。
客户端向服务器发送HTTP
数据包,请求创建握手。
GET /chat HTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: xxxxxxxxxx Sec-WebSocket-Version: 13
具体的细节我就不描述了,本身去查阅文档。
客户端发送HTTP
请求,首部Upgrade: websocket
,表示客户端但愿将通讯协议从HTTP
升级为WebSocket
协议。
服务器返回响应,赞成切换协议。
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xxxxxxxxxx
HTTP
响应状态码101
,切换协议。
握手以后即创建起了链接,开始全双工通讯。
WebSocket
与HTTP
协议相似,其资源地址相似:ws://server.example.com:8080/path
。
本文共同讨论了WebSocket
协议的一些理论基础,夜深了,先写到这里。
下一篇文章,使用spring-boot
实现简易的WebSocket
示例。