说起即时通讯大家应该都听过,像各种聊天软件用到的即时通讯技术是最多的。另外开发过程中实现消息推送最传统的做法就是轮询,即按照特定时间间隔由浏览器对服务器发送请求,以获取最新消息,这种传统模式带来很明显的缺点,即浏览器需要不断的向服务器发送请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样回浪费很多带宽等资源。
这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。
WebSocket是一种在单个TCP连接上进行全双工通信的协议。
WebSocket使得客户端和服务端之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
websocket运用场景:
- 即时通讯:多媒体聊天;
- 互动游戏:多人游戏;
- 协同合作:开发人员代码管理工具;
- 动态数据报表:类似通知变更;
- 实时工具:如导航,实时查询工具等也可使用。
原理
WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。
首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,如下所示:
GET ws://localhost:8181 HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:8181
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13
该请求和普通的HTTP请求有几点不同:
- GTE请求的地址不是类似/path/,而是以ws://开头的地址;
- 请求头Upgrade:websocket和Connection: Upgrade表示这个连接将要被转换为WebSocket连接;
- Sec-WebSocket-Key是用于标识这个连接,并非用于加密数据;
- Sec-WebSocket-Version指定了WebSocket的协议版本。
随后服务端如果接收该请求,就会返回响应,如下所示:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string
该响应代码101表示本次连接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket指定的WebSocket协议。
为了创建WebSocket连接,需要通过浏览器发送请求,然后服务器端响应,这个过程通常称为“握手”。
版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用WebSocket的API,就不需要关心这些。
现在,一个WebSocket连接就建立成功,浏览器和服务器就可以随时发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样处理起来方便些。
这里有个比较有意思的点,为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求 - 应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了以下:“接下来咱们通信不用HTTP协议了,直接互发数据吧”。
HTTP协议与WebSocket协议对比:
WebSocket目前支持两种统一资源标识符ws和wss,类似于HTTP和HTTPS。
其他特点:
- 建立在TCP协议之上,服务器端的实现比较容易;
- 与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用HTTP协议,因此握手时不容易屏蔽,能通过各种HTTP代理服务器;
- 数据格式比较轻量,性能开销小,通信高效;
- 可以发送文本,也可以发送二进制数据;
- 没有同源限制,客户端可以与任意服务器通信;
- 协议标识符是ws(如果加密,则为wss),服务器网址就是URL。
ws://example.com:80/some/path
浏览器支持:
目前支持WebSocket的主流浏览器如下:
- Chrome;
- Firefox;
- IE >= 10;
- Sarafi >= 6;
- Android >= 4.4;
- IOS >= 8。
客户端实现:
vue文件
服务器端实现:
server.js
这里客户端是node服务器,仅是一个简单的示例。
以上就是相关WebSocket技术知识的整理,希望对大家有用。