WebSocket 之协议基础

引言

随着Web领域的飞速发展,最初设计得十分简单的HTTP协议在当今的应用上显得捉襟见肘,协议的瓶颈也逐渐显露出来。web

“既然HTTP这么烂?为何咱们不抛弃它再设计一个全新的协议,而是要给他打补丁呢?”这是某次我和我舍友在宿舍喝着小酒,探讨SpringMVC时谈到的一个话题。spring

最初的HTTP,只是想把HTTP看成传输HTML文档的协议,设计者没有想到HTTP经久不衰,须要承受愈来愈复杂的业务职责。浏览器

因此HTTP的设计无可厚非,只是它不“那么地”适应这个时代了。可是目前基于HTTP协议实现的Web浏览器遍及全球,并不能随意动摇HTTP的地位。服务器

因此为了知足现代社会日益增加的业务需求,涌现出无数企图“消除”HTTP瓶颈的解决方案,其中的一项就是——“WebSocket”。微信

栗子

为何会出现WebSocket协议呢?websocket

image.png

假设咱们去实现相似微信同样的网页在线聊天工具,咱们要解决什么问题呢?网络

很显然,消息推送是当前业务场景下的一个技术瓶颈。异步

当前帐号收到了消息,咱们怎么在网页里“实时地”获取到消息并显示呢?注意要保障在线聊天的实时性。socket

方案一:只使用HTTP

能实现吗?显然不能。spring-boot

浏览器向客户端发起HTTP请求,请求到含有当前消息的HTML文件,渲染给用户。请求结束,不考虑持久链接的状况下,断开TCP链接。

当服务器有新消息时,除非用户当前网页刷新,不然在只使用HTTP的状况下没法实现实时性。

方案二:再加上Ajax

Ajax意思就是用 JavaScript执行异步网络请求。
——《廖雪峰的 JavaScript教程》

使用Ajax,能够在浏览器内用JavaScript“偷偷”地发起网络请求,查询最新的消息,下降操做成本,提高用户体验。

为了保证明时性,须要前台定时发送Ajax请求。例如:每5s发送一次网络请求查询消息,将数据的延时性保持在固定间隔之内。

缺点很明显,会产生大量的HTTP请求,若是消息长时间没有更新,十分浪费通讯资源。

方案三:再加上Comet

为了不产生大量无用的HTTP请求,产生了Comet

Ajax发起查询消息的请求,服务器接收到该消息,不会当即响应,Comet会将响应置于挂起状态,当服务器端有内容更新时,再返回响应。

与方案二相比,减小了无用的HTTP请求,同时也保证了数据的实时性。

缺点就是服务器压力过大,服务器为了保持挂起的HTTP响应,会消耗更多的宝贵的服务器资源。

方案四:WebSocket

由于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,切换协议。

通讯

握手以后即创建起了链接,开始全双工通讯。

WebSocketHTTP协议相似,其资源地址相似:ws://server.example.com:8080/path

总结

本文共同讨论了WebSocket协议的一些理论基础,夜深了,先写到这里。

下一篇文章,使用spring-boot实现简易的WebSocket示例。

相关文章
相关标签/搜索