WebSocket协议-概念原理

IT知识
29
0
0
2024-10-16
标签   websocket

Part1WebSocket是什么

WebSocket是一种网络传输协议,可以在单个TCP连接上进行全双工通信,它位于OSI模型的应用层。

WebSocket与HTTP不是同一种协议,虽然两者都位于OSI模型的应用层,并且都依赖底层的TCP协议。它们有着各自的协议格式,应用不同的场景。WebSocket协议本身不依赖于HTTP协议,但是在WebSocket最初的建立阶段依赖于HTTP,因为在WebSocket的握手过程使用了HTTP请求来升级协议。

WebSocket协议URL与HTTP类似,明文协议scheme为ws:,对应到HTTP协议是http:。基于SSL/TLS的WebSocket协议的scheme为wss:, 对应到HTTP协议是https:。ws默认端口为80,wss默认端口为443。

Part2为什么需要WebSocket

web通信已经有了HTTP协议,为啥还要搞一个WebSocket协议呢?一定是HTTP协议不能满足某些场景下的需求。下面先分析HTTP协议存在问题,然后分析WebSocket是如何工作的。

1HTTP协议

HTTP是请求应答通信模型,即客户端主动向服务器发送Request请求,服务器回复Response数据。服务器无法主动地向客户端发送资源,所以HTTP协议下客户端和服务器之间是非对称工作方式,是一种半双工通信。

当客户端向服务器发送一个HTTP请求时,客户端和服务器之间打开一个TCP连接,并且在接收到响应后,这个TCP连接会被终止。每个HTTP请求都会向服务器打开一个单独的TCP连接,如果客户端向服务器发送了10个请求,就会打开10个独立的TCP连接。

HTTP协议存在如下问题:

  • 实时性差:通过前面HTTP协议介绍可以看到,HTTP采用的是请求应答模型,服务器无法主动向客户端发送消息。无法满足一些应用场景需求,像在线游戏、实时数据更新。如果采用HTTP协议实现,需要通过轮询来实现,及时性很差。
  • 性能不高:每次请求都会打开TCP连接,请求应答后连接关闭,在频繁通信的场景下,这种频繁TCP建立连接和关闭连接,很消耗性能。

所以引入WebSocket协议解决HTTP存在的问题。

2WebSocket协议

WebSocket协议交互过程如下图,整个过程分为两个阶段。阶段1:进行握手。阶段2:进行数据传输。

握手

出于兼容性考量,握手采用HTTP来实现。客户端发送的握手消息是一个带有Upgrade头的HTTP Request消息。具体长下面这样。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
  • 通过GET发送HTTP请求,需要HTTP版本号>=1.1
  • Host:主机名,用于客户端和服务端都能验证它们是否使用的是同一个主机
  • Upgrade: 升级到WebSocket协议
  • Connection:连接类型应该被升级,通常与Upgrade一起使用
  • Sec-WebSocket-Key:随机生成的16字节内容,然后通过Base64编码。确保服务端能够正确地响应客户端的请求,从而验证服务端的身份
  • Sec-WebSocket-Protocol:指定使用哪个协议
  • Sec-WebSocket-Version:客户端可以接受哪些子协议

服务端回复给客户端的报文如下。

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
  • 101: 服务端响应101状态码,任何非101状态码都会导致错误,意味着WebSocket握手未完成
  • Sec-WebSocket-Accept:将客户端传过来的Sec-WebSocket-Key 和全局唯一标识符组合后的Base64编码哈希值。

如果Sec-WebSocket-Accept的值与预期值不匹配,缺少头字段或者HTTP状态码不是101,那么连接将不会被建立,也不会发送数据帧。

发送数据

WebSocket数据帧格式如下:

  • FIN:占1个bit,标记这个帧是不是消息中的最后一个帧,第一个帧也可以是最后一个帧。因为在WebSocket通信中,一个完整的消息可能需要分成多个帧来传输,而FIN字段就用来告诉对方是否还有后续的帧。
  • RSV1/RSV2/RSV3:各占1个bit,值必须是0。
  • opcode:操作码,占4个bit, 表示数据载荷 payload data类型,详情见下表。
  • MASK:掩码标识,占1个bit。表示载荷数据 payload data是否被掩码。如果设置为1,Masking-key部分有一个掩码钥匙,用这个钥匙对载荷数据进行掩码操作。
  • Payload len: 数据长度,占用7/(7+16)/(7+64)个bit位。如果值在0-125之间,则该值大小就表示数据长度。如果值为126,则接下来的两个字节(16bit)表示的16位无符号整数即为数据长度。如果值为127,则接下来八个字节(64bit)表示的64位无符号整数即为数据长度。
  • Masking key:掩码钥匙,占用0或4个字节,所有客户端发送到服务端的数据必须使用一个32位值进行掩码。
  • Payload data:应用数据。

操作码值

含义

0

继续帧

1

文本帧

2

二进制帧

3-7

保留

8

关闭帧

9

ping帧

10

pong帧

11-15

保留

Part3WebSocket使用场景

1实时Web应用程序

实时Web应用程序使用WebSocket连接来展示服务器发送的数据。例如,在交易网站或股票交易中,价格总是波动,向客户端展示价格时延迟要尽可能小。

2游戏应用程序

在游戏应用程序中,客户端持续向服务器发送数据,然后服务器在不刷新用户界面的情况下将数据发送回客户端。

3聊天应用程序

大多数聊天应用程序使用WebSocket提供用户之间不间断和快速的通信渠道。

4实时协作编辑

像各种云文档,例如腾讯文档、石墨文档等。

5实时数据可视化

前端可以通过WebSocket通道从后端获取数据,自动更新数据图表,如条形图、饼图等。在数据统计分析、数字化大屏领域用的很多。

6实时定位应用

移动应用中实时共享位置更新。

7语音识别应用

语音识别,实时返回识别后的文字。