文章目录
- 备注
- 一、什么是WebSocket
- 二、为什么要有WebSocket
- 三、WebSocket特点
- 四、WebSocket的帧结构
- 五、WebSocket建立连接(握手)的过程
- 六、WebSocket应用场景
- 七、WebSocket和SSE对比
发送数据强制使用掩码的原因
提供基本的防护,保证每次的消息都是随机的,抵御缓存中毒攻击,但如果运行在SSl/TLS上就没必要了
JS如何发送ping数据帧保活
//这里我们每隔 5 秒钟向服务器发送一个 Ping 帧,//并带上 type 参数值为 ping 的字符串。服务器收到 Ping 帧后,应该立即回复一个 Pong 帧,//并包含 type 参数值为 pong 的字符串,以保持连接的活跃。const webSocket = new WebSocket("wss://example.com");// 每隔 5 秒钟发送一次 Ping 帧setInterval(function() { if (webSocket.readyState === WebSocket.OPEN) { webSocket.send(JSON.stringify({ type: "ping" }), { fin: true, opcode: 0x9 }); }}, 5000);
- 将WebSocket拆开来看,WEB指的是HTTP、Socket指的是套接字调用。那么两个连起来就是WebSocket的含义了。WebSocket就是运行在"Web"上,也就是HTTP上的Socket通信规范,提供与 “TCP” Socket类似的功能,使用它可以像"TCP Socket"一样调用下层协议栈,任意的收发数据。
- WebSocket是基于TCP的轻量级网络通信协议,和HTTP属应用层,它俩是平级的。可以理解为TCP OVER WEB
为了弥补Http协议某方面的缺陷,比如Http2针对队头阻塞引入的多路复用。WebSocket就是为了解决HTTP协议“请求-应答模式”而诞生的。
请求-应答模式的不足:
- 是一种"半双工"的通信模式,虽然双方可以都发出数据,但是同一时刻只能收或者发。
- 是一种被动的通信模式,服务器端只能被动响应客户端的请求,而无法主动发送数据。虽然后来的Http/2 Http/3新增了Stream、Server Push等特性,但是“应答-请求“仍然是最主要的工作模式。这就导致 HTTP 难以应用在动态页面、即时消息、网络游戏等要求“实时通信”的领域。
在WebSocket出现之前,因为浏览器是一个受限的沙盒环境,不能使用TCP,所以WEB环境开发只能使用Http轮询来模拟实时通信的效果,但是代价大效率低。所以WebSocket就应运而生了,早期是Html5的一部分,后来自立门户,成了一个单独的标准。RFC文档编号是6455
3.1 全双工
WebSocket是真正“全双工”的通信协议,和TCP一样,客户端和服务端都可以随时向对方发送数据。而不用像Http一样“你拍一我拍一”。这样服务器可以更加主动,一旦有新数据可以推送给客户端,而不用轮询。
3.2 数据传输使用二进制帧
WebSocket 采用了二进制帧结构,语法、语义与 HTTP 完全不兼容,但因为它的主要运行环境是浏览器,为了便于推广和应用,就不得不“搭便车”,在使用习惯上尽量向 HTTP 靠拢,这就是它名字里“Web”的含义。
3.3 服务地址沿用HTTP格式
服务发现方面,WebSocket 没有使用 TCP 的“IP 地址 + 端口号”,而是延用了 HTTP 的 URI 格式,但开头的协议名不是“http”,引入的是两个新的名字:“ws”和“wss”,分别表示明文和加密的 WebSocket 协议。
3.4 默认端口为80和443
因为现在互联网上的防火墙屏蔽了绝大多数的端口,只对 HTTP 的 80、443 端口“放行”,所以 WebSocket 就可以“伪装”成 HTTP 协议,比较容易地“穿透”防火墙,与服务器建立连接。这里的伪装指的是WebSocket利用HTTP的协议升级机制来建立TCP连接,这样就绕过了浏览器沙盒和网络防火墙这些机制。
ws://www.chrono.comws://www.chrono.com:8080/srvwss://www.chrono.com:445/im?user_id=xxx
WebSocket的侧重点是实时通信,和Http2等侧重于传输效率的协议不同,所以二者的帧也有很大的区别。
- WebSocket 虽然有“帧”,但却没有像 HTTP/2 那样定义“流”,也就不存在“多路复用”“优先级”等复杂的特性。
- 而它自身就是“全双工”(TCP) 的,也就不需要“服务器推送”。
数据帧的组成:“结束标志位 + 操作码 + 帧长度 + 掩码”
开头第一个字节
- 第一位:FIN标志位是消息结束的标志位,相当于 HTTP/2 里的“END_STREAM”,表示数据发送完毕。一个消息可以拆成多个帧,接收方看到“FIN”后,就可以把前面的帧拼起来,组成完整的消息。
- 第二位到第四位:三个位是保留位,目前没有任何意义,但必须是 0
- 第五个字节到第八个字节:Opcode操作码,用来标识帧类型。比如1标识帧内容为纯文本,2 表示帧内容是二进制数据,8 是关闭连接,9 和 10 分别是连接保活的 PING 和 PONG。
开头第二个字节
- 第一位:MASK 掩码标识位,表示帧内容是否使用异或操作(xor)做简单的加密。目前的 WebSocket 标准规定,客户端发送数据必须使用掩码,而服务器发送则必须不使用掩码。
- 后七位:Payload len 表示帧内容的长度。它是另一种变长编码,最少 7 位,最多是 7+64 位,也就是额外增加 8 个字节,所以一个 WebSocket 帧最大是 2^64。
Payload len字段后的Masking-key
- 掩码密钥,它是由上面的标志位“MASK”决定的,如果使用掩码就是 4 个字节的随机数,否则就不存在。
和TCP、TLS一样,WebSocket建立连接也需要先进行握手,然后才能正式收发数据!握手还蹭上了HTTP的便车,利用了Http的协议升级特性来握手,也正是这样才能绕过浏览器沙盒和网络防火墙。
5.1 握手请求阶段
- 客户端向服务器发送一个 HTTP GET 请求,并附带 Upgrade 头和 Connection 头,以表明客户端希望升级到 WebSockets 协议。
- “Connection: Upgrade”,表示要求协议“升级”;
- “Upgrade: websocket”,表示要“升级”成 WebSocket 协议。
- 为了防止普通的 HTTP 消息被“意外”识别成 WebSocket,握手消息还增加了两个额外的认证用头字段。
- Sec-WebSocket-Key:一个 Base64 编码的 16 字节随机数,作为简单的认证密钥;
- Sec-WebSocket-Version:协议的版本号,当前必须是 13。
5.2 握手响应阶段
- 确认握手请求没问题后,服务器将生成一个 Sec-WebSocket-Accept 头,该头包含对客户端提供的 Sec-WebSocket-Key 头的加密验证结果,并附带 Upgrade 和 Connection 头。如果浏览器没有接受token,加密验证失败终止握手过程。加密具体的做法是把请求头里“Sec-WebSocket-Key”的值,加上一个专用的 UUID “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,再计算 SHA-1 摘要 。
base64(Sha1(Sec-WebSocket-Key+258EAFA5-E914-47DA-95CA-C5AB0DC85B11))
- 服务器将握手响应作为 HTTP 101 状态码和一个 “Switching Protocols” 消息体来返回,标识WebSockets 握手已经成功,服务器与客户端当前正在使用 WebSockets 协议进行通信。
- 握手完成后,客户端和服务器之间的连接会保持打开状态,直到其中一个端点发送了一个 CLOSE 帧,或者有网络故障发生,或者超过了连接的时间限制或带宽限制为止。
即时通讯
通过 Websockets 可以实现即时通讯,无需刷新页面。这种应用场景包括在线聊天、多人游戏、实时投票等。
多人协作
对于需要多人协作的应用,Websockets 可以实现实时同步。例如在线文档编辑器、团队协作工具等。
实时数据可视化
Websockets 可以实时更新数据,使得应用可以实现实时数据可视化。这种应用场景包括数据监控、股票交易、实时地图等。
视频和音频流
Websockets 可以传输视频和音频流,使得应用可以实现实时音视频通讯、远程会议、视频直播等。
消息推送和轮询
传统的 HTTP 请求和轮询方式费时费力,而 Websockets 可以实现服务器主动向浏览器推送消息,优化客户端体验。这种应用场景包括新闻订阅、邮件提醒、社交网络消息通知等。
总的来说,Websockets 协议可以为 Web 应用程序提供实时双向通讯的能力,更好的解决了 Web 应用程序实时性的问题,从而实现了更多的创新和应用。
Server-Sent Events 是一种基于HTTP相应流实现服务器推送功能的技术
- 数据交换方式不同 WebSocket 采用双向通信交换数据,而 SSE 采用服务器向客户端单向推送数据。
- 协议和性能的区别 WebSocket 使用更复杂的协议,需要更多的处理开销,但它具有更低的延迟和更好的性能,可以支持更复杂的应用场景;SSE 的基于 HTTP 的实现方式相对简单,不需要额外的协议,性能相对 WebSocket 稍逊。
- 安全性 WebSocket 需要专门的服务器端支持,需要处理跨域问题;而 SSE 不需要支持 WebSocket 的服务器端,可以直接在普通的 HTTP 服务器上实现,同时也可以支持跨域请求。
- 功能适用性 WebSocket 更适用于双向数据传输的应用场景,如即时聊天、游戏等;而 SSE 更适合单向数据推送的场景,如新闻、股票行情、天气预报等。
来源地址:https://blog.csdn.net/weixin_40979518/article/details/130097526