简单但全面了解一下webSocket

@toc

webSocket是一种协议,设计用于提供低延迟双全工长期运行的连接

**全双工:**通信的两个参与方可以同时发送和接收数据,不需要等待对方的响应或传输完成。双全工指的是一种通信方式,通过建立全双工的持久连接客户端和服务器之间就能实现高效实时性更强的通信。

什么是实时通信

传统通信 : 电子邮件、网页浏览存在延迟,需要用户主动请求来获取更新数据。 实时通信: 即时消息传递(即时聊天)、音视频通话、在线会议和实时数据传输等,可以实现即时的数据传输和交流,不需要用户主动请求或刷新来获取更新数据。

webSocket之前的世界

在webSocket出现之前实现实时通信主要通过以下几种技术来解决:

  1. 轮询:客户端定期向服务器发送请求,询问是否有新的数据可以用服务器在接收到请求后再检查是否有更新的数据,并将其返回给客户端。 缺点: 产生大量的请求和响应,导致不必要的网络开销和延迟。
  2. 长轮询: 在客户端发出请求后,服务器会保持连接打开一段时间,等待新数据响应后再关闭连接。是基于HTTP的技术 优点:解决了无效轮询的数量 缺点:需要频繁的建立和关闭连接
  3. Comet:Comet和长轮询一样是基于HTTP的技术,和长轮询不同的是它可以在返回请求后在返回请求后继续保持连接打开,它的核心思想就是通过保持长连接来模拟实时通信并允许服务器通过流式传输,iframe等推送技术来 主动向客户端推送数据,不过Comet虽然可以模拟实时通信但是它仍然是基于HTTP的模型,在Comet中服务器推送数据给客户端的方式通常还是通过延长响应或使用推送技巧来实现的。

webSocket的优势

总的来说,webSocket相比起其他的技术,有着以下这些优势:

  1. 双向实时通信 允许在单个、长时间的连接上进行双向实时通信。需要在快速实时更新的应用程序里,比HTTP更加高效。WebSocket允许服务器主动向客户端推送数据,而不需要客户端发起请求。这种服务器推送的机制可以实现实时更新数据的功能,避免了客户端频繁地发送请求来获取最新数据的需求。

  2. 降低延迟 webSocket的连接一旦建立便会保持开放,数据可以在客户端和服务器之间比HTTP更低的延迟进行传输。

  3. 更高效的资源利用 可以减少重复请求和响应的开销,因为它的连接只需要建立一次。WebSocket在通信过程中的头部开销相对较小。HTTP协议每次请求都需要发送完整的头部信息,而WebSocket只需要在建立连接时发送一次头部信息,之后的通信只需要发送数据本身,减少了额外的开销。

  4. 二进制数据支持: WebSocket支持传输二进制数据,而HTTP协议主要用于传输文本数据。对于一些需要传输大量二进制数据的应用场景,WebSocket可以更高效地进行数据传输。

(这里补充一下HTTP协议:HTTP是一种无状态的协议,每次请求都需要建立一个新的连接,完成请求后立即关闭连接) 可以说webSocket的出现填补了传统的HTTP协议在实时通信方面的不足,它允许客户端和服务器之间通过单个TCP连接进行双工通信,并且进行实时的数据交换,所以webSocket的协议非常适用于基于Web的游戏、聊天应用以及任何低延迟实时连接的应用程序。目前的webSocket已经得到了主流浏览器的支持,而且由于webSocket的标准定义了一套通信规范,所以无论是JavaScript、Java还是其他编程语言都存在相应的库、框架或者模块来支持WebSocket的实现和使用,比如JS就有Socket.io

那么要如何建立一个webSocket连接呢? webSocket的建立需要通过HTTP发送一次常规的Get请求,并且在请求头中带上Upgrade,告诉服务器我想要从HTTP升级为WebSocket连接就建立成功了,之后客户端和服务器双方便可以随时向彼此发送信息。

后端部分用的node.js 先是引用了http和webSocket模块,先创建一个http实例,然后通过它再创建webSocket服务器,当有客户端连接到wenSocket服务器时就会触发Connection事件,当从客户端接收到消息时候会触发Message事件会接收一个参数表示从客户端那里接收到的消息内容

为什么需要心跳机制?

为了保持webSocket稳定的长连接,连接状态可能会因为各种原因发生变化,在连接建立之后,服务器和客户端之间通过心跳包来保持连接状态,以防止连接因为长连接没有数据传输而被切断。 心跳包就i是一种特殊的数据包,不包含任何实际数据,仅用来维持连接状态,通常情况下心跳包由客户端和服务器端定期发送一个空的数据帧,以确保双方的连接仍然有效,避免连接因为长时间没有数据传输而被中断,如果在一段时间内没有收到对方的心跳包就可以认为连接已经断开需要重新建立连接。

为什么发送空的数据帧就可以确保双方连接有效?

  1. 保持连接活跃:WebSocket连接在一段时间内没有数据传输时,可能会由于网络设备的超时机制或其他原因被关闭。通过定期发送空的数据帧,可以向服务器发送一个信号,告知连接仍然活跃,防止连接被关闭。

  2. 检测连接状态:发送心跳包可以帮助检测连接是否正常。如果客户端或服务器在一定时间内没有收到心跳包,就可以判断连接可能已经断开。这样可以及时采取措施,例如重新建立连接或通知用户连接中断。

  3. 节省带宽和资源:发送空的数据帧相比发送实际数据,可以减少数据传输的带宽消耗和服务器资源占用。心跳包通常只包含一些固定的控制信息,不需要传输大量的数据,因此可以降低网络负载和服务器负载。

  4. 快速检测连接中断:由于心跳包是定期发送的,一旦连接中断,客户端或服务器可以迅速发现连接断开的情况。这样可以更快地采取恢复措施,提高连接的可靠性和用户体验。

需要注意的是,心跳包的发送频率应根据具体应用的需求进行调整。发送过于频繁的心跳包可能会增加网络负载,而发送过于稀少的心跳包可能无法及时检测到连接中断。因此,需要根据实际情况选择合适的心跳包频率。

webSocket的限制

  1. 不提供加密功能 如果有安全上的需求,需采用其他方式来确保安全性,如SSL协议对webSocket连接进行加密,防止敏感信息被窃听或者篡改,另外也可以限制访问的权限,在服务端设置黑名单或者白名单只允许特定IP地址或者域名的客户端进行连接。
  2. 不支持古老的浏览器 不支持IE10以前的版本。需要使用AJAX或者其他方式来进行替代
  3. 优化很重要 除此之外,当webSocket连接过多时可能会对服务器的性能造成负面影响,因为webSocket是一个长连接,需要服务器不断的维护和处理连接状态,优化性能。
相关推荐
清秋24 分钟前
全网最全 ECMAScript 攻略( 更新至 ES2026)
前端·javascript·编程语言
Cao_Ron42 分钟前
用 SVG image symbol 画 ECharts graph 圆形节点
前端
hxy06011 小时前
React-Call让你的React组件像异步函数一样调用
前端·react.js
Hilaku1 小时前
为什么 AI 写前端时,总是优先选择 React,而不是 Vue?
前端·javascript·程序员
京东云开发者1 小时前
GPT-5.6、ChatGPT Work 与 Codex 更新食用指南
前端
Cao_Ron1 小时前
用 ECharts graph 画出卡片式矩形节点
前端
skiyee1 小时前
换个底座的 Wot Starter 居然让 AI 更懂项目!
前端·ai编程
anyup1 小时前
这一套绝了!AI 大模型写故事,星云 SDK 驱动 3D 数字人实时演绎
前端·人工智能·aigc
耀耀切克闹灬2 小时前
短链跳转
前端
孟陬2 小时前
高质量全方位的 AI 工具 sse-stuntman — Mock SSE 接口
前端·node.js·openai