【WebSocket】原理介绍

参考资料:
一文吃透WebSocket原理

什么是 WebSocket

  1. 单tcp 全双工
  2. 服务端主动向客户端推送
  3. 计算机网络应用层协议,弥补http协议在持久通信能力的不足
  4. 服务器推送技术
  5. TCP上
  6. 与HTTP兼容,默认端口 80 和 443
  7. 握手阶段用HTTP协议
  8. 数据格式轻量
  9. 可以发送文本/二进制数据
  10. 协议标识ws,如果加密,则是wss

为什么需要 websocket

HTTP的缺陷:通信只能由客户端发起,不具备服务器推送能力。如果服务器有连续的状态变化,客户端只能轮询,效率低且浪费资源

服务端被迫维持来自每个客户端的大量不同连接

大量轮询请求会造成高开销,比如带上多余的header,造成无用的数据传输

WebSocket和HTTP的区别

图源:见参考文章

WebSocket建立握手时,是通过HTTP建立,但是建立后传输时不需要HTTP。

  1. Websocket 是双向通信协议,可以双向发送或接受信息,HTTP是单向的;
  2. HTTP/2 也可以主动推送,但是推送的是静态资源,不能推送指定信息。

WebSocket 协议原理

一个 WebSocket 握手的例子

js 复制代码
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
  • Upgrade: 升级头,告诉服务器我想用的是 websocket 协议
  • Connection: 连接头,配合upgrade,告诉服务器本次连接需要升级
  • Sec-WebSocket-Key: WebSocket专用,客户端随机生成的16字节随机数,经过 Base64 编码后的字符串。避免服务端把普通HTTP请求误判为WebSocket请求,并且起到握手校验的作用,服务端会将这个key拼接上固定字符串,做哈希后再进行Base64编码,生成 Sec-WebSocket-Accept 响应头返回给客户端,客户端校验后才算握手成功。
  • Sec-WebSocket-Protocol: WebSocket子协议头,客户端声明"我支持的 WebSocket 子协议",多个子协议用逗号分开。
    • 作用是协商应用层协议,比如聊天系统可能定义 chat 子协议,文件传输定义 file 子协议,服务端可以选择其中一个或拒绝。
    • 子协议是业务层约定,不是 websocket核心协议,可以省略。
    • 是用户定义的字符串,用来区分同一个URL下,不同服务所需要的协议。
  • Sec-WebSocket-Version: WebSocket 版本头,含义是客户端支持的 WebSocket 版本,服务端只支持特定版本,如果客户端版本不匹配,服务端会返回426 Upgrade Required错误,并告知支持的版本。

服务端响应

js 复制代码
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
  • Upgrade: 告诉客户端即将升级的是 websocket 协议
  • Connection: 配合Upgrade
  • Sec-WebSocket-Accept: 经过服务器确认,加密过后的 Sec-WebSocket-Key。
  • Sec-WebSocket-Protocol: 表示最终使用的协议

WebSocket 建立连接的过程

客户端发起HTTP请求,经过3次握手后,建立起TCP连接,HTTP请求中放WebSocket 支持的版本号等信息;

服务端收到客户端的HTTP请求后,采用HTTP协议返回数据;

客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工传输。

应用场景

  • 即时聊天通信
  • 多玩家游戏
  • 在线协同编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置
  • 即时web应用程序 即时Web应用程序使用一个web套接字在客户端显示数据,数据由后端服务器连续发送,在websocket中数据被连续推送、传输到已打开的同一个连接中。
  • 聊天应用程序:聊天应用程序仅使用websocket建立一次连接,能在订阅户之间交换、发布和广播消息,重复使用相同的websocket连接,用于发送和接收消息以及一对一的消息传输。

不适用的场景

获取旧数据或者只想获取一次数据供应用程序使用,这种情况用HTTP即可。

如果仅加载一次数据,RESTful Web 服务足以从服务器获取数据。

WebSocket 断线重连

为什么需要 WebSocket 心跳

心跳:客户端定时给服务端发送消息,证明客户端是在线的,如果超过一定时间没有发送就是离线了。

WebSocket 是长连接,实际网络中存在"隐性断开"的场景,比如网络波动,防火墙/代理超时,客户端异常退出等,心跳机制核心目的是主动检测连接的活性,及时发现断开的连接,清理无效资源。

心跳是单向/双向的定时交互,这里以"客户端主动发心跳,服务端校验"为例。

有几种不同的设计方案,有的是在客户端设置定时器:

  • 客户端每隔一个时间间隔发送一个探测包给服务端,
  • 客户端发包时启动一个超时定时器,
  • 服务端接收到检测包,回应一个包,
  • 如果客户端接收到服务端的应答包,则说明服务端正常,删除超时定时器,
  • 如果客户端的超时定时器超时,依然没有收到应答包,说明服务器挂了。
相关推荐
芯智工坊7 分钟前
第8章 Mosquitto消息高级特性
网络·人工智能·mqtt·开源·ssl
rOuN STAT12 分钟前
PLC(电力载波通信)网络机制介绍
开发语言·网络·php
芯智工坊16 分钟前
第7章 Mosquitto增加SSL/TLS加密通信
网络协议·https·ssl
EmbeddedCore17 分钟前
低成本物联网产品放弃SSL加密的隐形成本与市场逻辑
物联网·网络协议·ssl
数据知道22 分钟前
claw-code 源码详细分析:命令宇宙 vs 工具宇宙——`commands` / `tools` 镜像清单如何驱动路由与 shim 执行?
linux·服务器·网络·python·ai·claude code
婷婷_17225 分钟前
DWC Ethernet QoS VLAN功能实现详解
网络·学习·程序人生·ethernet·芯片·vlan·gmac
测试摆渡媛26 分钟前
UDS诊断
网络
minji...32 分钟前
Linux 多线程(三)线程控制,线程终止,线程中的异常问题
linux·运维·服务器·开发语言·网络·算法
Benszen37 分钟前
一些存储类型
网络·网络协议·rpc
vortex538 分钟前
一文厘清DDoS与CC攻击
网络·网络安全·渗透测试·ddos