WebSocket是一种在单个TCP连接上进行全双工通信的协议。
WebSocket允许客户端和服务器之间进行实时的双向通信。这意味着服务器可以主动推送数据到客户端,而不需要客户端每次都发送请求来获取数据。这种通信方式通过长连接实现,即连接建立后,可以持续进行数据传输,直到一方主动关闭连接。
传统的通信方式,比如电子邮件或者普通的网页浏览,通常都会存在一定的延迟。需要用户主动地请求来获取更新数据。
而实时通信,通过利用及时传输的技术和协议,使得数据能够立即传输给接收方。他也因此普遍被运用在及时聊天,在线会议,协同编辑等环境下。
通过建立全双工的持久连接,客户端和服务器之间,就能实现高效、实时性更强的通信。
可以说WebSocket的出现,就是为了解决实时通信的问题。
在WebSocket出来之前,实时通信问题主要通过以下几种技术来解决 :
总的来说,WebSocket相比起其他的技术,有着以下这些优势 :
WebSocket的出现,填补了HTTP在实时通信方面的不足。他允许客户端和服务器,通过单个TCP连接进行双工通信,并且进行实时的数据交换。
目前的WebSocket技术,已经得到了主流浏览器的支持。而且由于WebSocket的标准定义了一套通信规范,所以无论是JavaScript还是Java、Python等各种语言,都存在相应的库。
WebSocket协议非常适用于基于Web的游戏、聊天应用,以及任何需要低延迟、实时连接的应用程序。比如 :
HTTP对单独的请求使用单独的连接,他增加了服务器的负载,因为服务器必须为每个请求创建新的握手。一旦请求完成,连接就会关闭。
而WebSocket,只要任何一方不中断连接,连接就是持久的。
WebSocket协议是一个独立的,基于TCP的协议。它与HTTP的唯一的关系是,HTTP服务器将其握手解析为升级请求。
WebSocket握手过程,是客户端和服务器之间建立实时通信通道的关键步骤。它利用熟悉的HTTP协议进行初始连接,然后协商升级到WebSocket协议。
具体连接步骤如下 :
客户端向服务器发起一个特殊的HTTP GET请求,这个HTTP请求包含一些关键的头部信息,用于表明客户端希望将通信协议从 HTTP 升级到 WebSocket。
Upgrade:WebSocket
: [重要] 升级WebSocket标头,告诉客户端想要升级到WebSocket连接。Connection:Upgrade
: [重要] 连接升级标头通知服务器希望从当前连接协议进行升级。Sec-WebSOcket-Key
: 密钥,是包含随机生成的,本次握手特有的Base64编码的字符串的标头。服务器稍后会使用它来验证握手。Sec-WebSocket-Version
: WebSocket
版本,目前主流的是13版本Sec-WebSocket-Protocol
: 用于指定客户端希望与服务器通信时所使用的子协议然后客户端等待服务器对于HTTP升级请求的相应。
服务器收到客户端的请求后,会检查请求头部是否符合WebSocket握手的要求。
Upgrade:WebSocket
和Connection:Upgrade
是否存在如果符合,服务器会生成一个特殊的响应来完成握手过程。响应的状态码是101,表示协议正在切换。
响应头部也会包含“Upgrade”和“Connection”字段,其值与客户端请求中的相同。
此外,服务器会解析 “Sec - WebSocket - Key” ,使用这个密钥来生成一个 “Sec - WebSocket - Accept” 响应头。并将其放在响应头部中返回给客户端。
一旦客户端收到,带有正确Sec
标头的服务端相应,它就会验证该相应,确认握手成功。
客户端和服务器,现在可以通过已建立的TCP连接,使用WebSocket协议交换数据,HTTP本质上被WebSocket取代。
WebSocket有一个默认的URI格式,可以是ws:
,也可以是wss:
ws:
,443端口用于wss:
为了将来协议扩展而预留的空间,目前通常设置为0
opcode = 0x00
掩码机制是用于对从客户端发送到服务器的数据帧进行加密处理的一种机制。主要是为了防止代理服务器、中间件等第三方设备被恶意利用来缓存和篡改数据。
用于告诉接收方这个帧中实际承载的数据长度是多少
是指 WebSocket
帧中包含的实际数据部分。这部分数据是通信双方真正想要传输的内容
片段(Fragments
)是指将一个完整的消息分割成多个 WebSocket
帧来进行发送的情况。当消息内容过长或者需要分块传输时,就会使用到片段。
FIN
标志位,用于指示这是否是消息的最后一个片段。如果FIN
为1
,则表示该帧是消息的结尾;如果FIN
为0
,则表示该帧是消息的一个中间片段。Sec - WebSocket - Key
是一个 Base64编码
的随机值。在每次客户端请求建立 WebSocket 连接时,这个值都是不同的。这种随机性使得攻击者很难猜测出正确的密钥来伪装成合法客户端。例如,它类似于一个每次进门都随机生成的 “门禁密码”,只有拥有正确密码(由客户端生成)的请求才能被服务器视为可能是合法的升级请求。
这种验证机制是 WebSocket 协议标准
的一部分。因为协议规定了双方都必须按照这个固定的方式进行密钥处理和验证,所以只要客户端和服务器都正确地实现了协议,就可以确保只有合法生成 Sec - WebSocket - Key
的客户端能够通过服务器的验证。
假设一个恶意攻击者试图伪造请求,它很难生成一个能够通过服务器验证的 Sec - WebSocket - Key
。因为 SHA - 1
哈希算法是单向的,攻击者几乎不可能从期望的 Sec - WebSocket - Accept
值反推出正确的 Sec - WebSocket - Key
。而且,由于 Sec - WebSocket - Key
是随机生成的,攻击者也很难猜测出一个有效的密钥来通过验证。
websocket是什么?和HTTP是什么区别?长轮询是什么?服务器推是什么?_哔哩哔哩_bilibili
10 分钟 理论 + 实操 搞懂 WebSocket_哔哩哔哩_bilibili
WebSocket的工作原理_哔哩哔哩_bilibili
WebSockets原理,握手和代码实现!用Socket.io制作实时聊天室_哔哩哔哩_bilibili