WebSocket | 背景 概念 原理 使用 优缺点及适用场景

1 背景

在 WebSocket 出现之前,为了实现推送技术,所用的技术都是轮询,轮询是指浏览器每隔一段时间向服务器发出 HTTP 请求,服务器再返回最新的数据给客户端
常见的轮询方式分为轮询与长轮询,它们的区别如下图所示:
在这里插入图片描述

这种传统的模式带来很明显的缺点,即浏览器需要不断向服务器发出请求,然而 HTTP 请求与响应可能会包含较长的头部,其中真正有效的数据可能只是很少的一部分,这样会消耗很多带宽资源。因此,HTML5 定义了 WebSocket 协议,能更好地节省服务器资源和带宽,并且能够更实时地进行通讯

2 什么是WebSocket

WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,它使得客户端和服务器之间的数据交换变得更加简单,只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输,本质上一种计算机网络应用层的协议,用来弥补 HTTP 协议在持久通信能力上的不足
它有以下特点:

  • 建立在 TCP 协议之上
  • 与 HTTP 协议有着良好的兼容性:与 HTTP 和 HTTPS 使用相同的 TCP 端口,可以绕过大多数防火墙的限制,默认端口是 80(ws) 和 443(wss,运行在 TLS 之上),并且握手阶段采用 HTTP 协议
  • 较少的控制开销:连接创建后,ws 客户端、服务端进行数据交换时,协议控制的数据包头部较小,而 HTTP 协议每次通信都需要携带完整的头部
  • 可以发送文本,也可以发送二进制数据
  • 没有同源限制,客户端可以与任意服务器通信
  • 协议标识符是 ws,如果加密则为 wss,服务器网址就是 URL
  • 支持扩展:ws 协议定义了扩展,用户可以扩展协议,或者实现自定义的子协议,比如支持自定义压缩算法

3 原理

3.1 建立连接

在 WebSocket 开始通信之前,通信双方需要先进行握手,WebSocket复用了 HTTP 的握手通道,即客户端通过 HTTP 请求与 WebSocket 服务端协商升级协议,协议升级完成后,后续的数据交换则遵照 WebSocket 的协议
利用 HTTP 完成握手有以下好处:

  • 可以让 WebSocket 和 HTTP 基础设备兼容(运行在 80 端口 或 443 端口)
  • 可以复用 HTTP 的 Upgrade 机制,完成升级协议的协商过程

3.2 交换数据

WebSocket 的每条消息可能会被切分成多个数据帧,发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息
以下是MDN 上的示例:

Client: FIN=1, opcode=0x1, msg="hello"
Server: (process complete message immediately) Hi.

Client: FIN=0, opcode=0x1, msg="and a"
Server: (listening, newmessage containing text started)

Client: FIN=0, opcode=0x0, msg="happy new"
Server: (listening, payload concatenated to previous message)

Client: FIN=1, opcode=0x0, msg="year!"
Server: (process complete message) Happy new year to you too!

在该示例中,客户端向服务器发送了两条消息,第一个消息在单个帧中发送,而第二个消息跨三个帧发送。当 WebSocket 的接收方收到一个数据帧时,会根据 FIN 字段值来判断是否收到消息的最后一个数据帧;利用 FIN 和 Opcode,我们就可以实现跨帧发送消息
其中 Opcode 表示操作码,它的可能值有:

  • 0x1:传输数据是文本
  • 0x2:传输数据是二进制数据
  • 0x0:表示该帧是一个延续帧,这意味着服务器应该将帧的数据连接到从该客户端接收到的最后一个帧
  • 0x3-7:保留的操作代码,用于后续定义的非控制帧
  • 0x8:表示连接断开
  • 0x9:表示这是一个心跳请求ping
  • 0xA:表示这是一个心跳响应pong
  • 0xB-F:保留的操作代码,用于后续定义的控制帧

具体的数据帧格式大概如下图所示,单位是比特:

  • FIN:1 个比特,值为 1 表示这是消息的最后一帧,为 0 则不是
  • RSV1, RSV2, RSV3:各占 1 个比特,一般情况下全为 0,非零值表示采用 WebSocket 扩展
  • Mask: 1 个比特,表示是否要对数据进行掩码操作
  • Payload length:数据负载的长度,单位是字节,为 7 位,或 7+16 位,或 1+64 位
  • Masking-key:0 或 4 字节(32 位),所有从客户端传送到服务端的数据帧,数据都进行了掩码操作,Mask 为 1,且携带了 4 字节的 Masking-key;如果 Mask 为 0,则没有 Masking-key
  • Payload data:具体数据
    在这里插入图片描述

3.3 维持连接

使用 WebSocket 进行通信,可以通过建立心跳机制来判断连接正常没有断开或者服务是否可用,所谓心跳机制,就是定时发送一个数据包,让对方知道自己在线且正常工作,确保通信有效;如果对方无法响应,便可以弃用旧连接,发起新的连接了
需要重连的场景可能包括:网络问题或者机器故障导致连接断开、连接没断但不可用了或者连接对端的服务不可用

发送方 -> 接收方:ping
接收方 -> 发送方:pong

ping 、pong 的操作,对应的是 WebSocket 的两个控制帧,Opcode 分别是 0x9、0xA。比如说,WebSocket 服务端向客户端发送 ping:

// ping
ws.ping()
// pong
ws.
<think>好的,我现在需要给用户介绍一下WebSocket。用户之前已经询问过MyBatis,现在转向WebSocket,可能是想了解网络通信相关的技术。首先,我应该回忆WebSocket的基础知识,确保自己理解正确。 WebSocket是一种在单个TCP连接上进行全双工通信的协议,不同于传统的HTTP请求-响应模式。用户可能知道HTTP的局限性,比如每次请求都需要建立连接,无法实现服务器主动推送,而WebSocket解决了这些问题。需要明确WebSocket的优势和应用场景。 接下来,思考用户可能的背景。他们可能是开发人员,想了解如何在项目中使用WebSocket,或者学生需要基础知识。考虑到之前的问题关于MyBatis,用户可能在做全栈开发,涉及前后端交互,WebSocket在实时通信方面很重要。 需要覆盖的内容包括:WebSocket的定义、工作原理、与HTTP的区别、使用场景优缺点、实现示例等。还要注意结构清晰,分点说明,帮助用户逐步理解。 可能需要注意的技术细节包括握手过程、数据帧结构、心跳机制等,但作为介绍,可能需要简化这些,避免过于深入。同时,应提到相关的库或框架,比如JavaScript中的WebSocket API,Spring Boot中的支持,方便用户进一步学习。 需要验证自己的记忆是否正确,例如,WebSocket的握手确实是通过HTTP Upgrade头实现的,端口默认是80或443,与HTTP相同。数据帧是否支持二进制和文本格式,以及如何维持长连接。 还要考虑用户可能的疑问,比如安全性(wss协议)、兼容性(浏览器支持情况)、性能影响(并发连接数)。是否需要给出简单的代码示例,比如前端和后端的实现片段,帮助用户直观理解。 最后,总结WebSocket适用场景,如实时聊天、在线游戏、股票行情等,对比其他技术如轮询、SSE,突出WebSocket的优势。确保回答准确、全面,结构清晰,符合用户之前得到的MyBatis回答风格。</think>--- ### 一、WebSocket 的核心概念 **WebSocket** 是一种基于 TCP 的网络协议,提供 **全双工(双向实时通信)** 能力。与传统的 HTTP 请求-响应模式不同,WebSocket 允许客户端与服务器建立持久连接,并实现数据的 **低延迟双向传输**。 --- ### 二、WebSocket 的核心特性 #### 1. **持久化连接** - **单连接多交互**:一次握手后,连接保持打开状态,可多次发送数据,避免 HTTP 的重复建连开销。 - **低延迟通信**:数据直接通过已建立的通道传输,无需等待请求响应周期。 #### 2. **协议升级机制** - **握手阶段**:通过 HTTP 协议升级实现,客户端发送请求头 `Upgrade: websocket`,服务器响应 `101 Switching Protocols`。 ```http // 客户端握手请求 GET /chat HTTP/1.1 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 服务器响应 HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= ``` #### 3. **数据帧格式** - **轻量级数据包**:支持文本(UTF-8)和二进制数据,帧头开销仅 2~14 字节。 - **掩码加密**:客户端发送的数据帧需掩码处理,防止中间代理缓存攻击。 --- ### 三、WebSocket 与 HTTP 的对比 | 特性 | WebSocket | HTTP | |--------------------|------------------------------------|------------------------------| | **连接方式** | 持久化单连接 | 短连接(请求-响应后关闭) | | **通信方向** | 全双工(双向实时) | 半双工(客户端主动发起) | | **数据传输效率** | 高(无重复建连、头部开销小) | 低(每次请求需完整头部) | | **适用场景** | 实时交互(聊天、游戏、监控) | 静态资源获取、表单提交 | --- ### 四、WebSocket 的典型使用场景 1. **实时通信应用** - 如在线聊天、弹幕系统、协同编辑工具(如 Google Docs)。 2. **高频数据推送** - 股票行情实时更新、物联网设备状态监控(如温度传感器每秒上报数据)。 3. **多玩家在线游戏** - 实时同步玩家位置、动作状态(如 MOBA 类游戏)。 4. **在线客服系统** - 支持用户与客服实时双向对话,提升响应速度。 --- ### 五、WebSocket 的实现示例 #### 1. 前端(JavaScript) ```javascript // 创建 WebSocket 连接(ws 表示非加密,wss 表示加密) const socket = new WebSocket('ws://localhost:8080/chat'); // 监听连接打开事件 socket.onopen = () => { socket.send('Hello Server!'); }; // 监听服务器消息 socket.onmessage = (event) => { console.log('收到消息:', event.data); }; // 监听连接关闭 socket.onclose = () => { console.log('连接已关闭'); }; ``` #### 2. 后端(Spring Boot) ```java @ServerEndpoint("/chat") // 声明 WebSocket 端点 @Component public class ChatEndpoint { @OnOpen public void onOpen(Session session) { System.out.println("客户端连接: " + session.getId()); } @OnMessage public void onMessage(String message, Session session) { // 处理消息并广播 session.getAsyncRemote().sendText("服务器回复: " + message); } @OnClose public void onClose(Session session) { System.out.println("连接关闭: " + session.getId()); } } ``` --- ### 六、WebSocket 的局限性及解决方案 1. **浏览器兼容性** - 旧版本浏览器(如 IE <10)不支持,可通过降级方案(如轮询)或使用兼容库(如 Socket.IO)解决。 2. **连接稳定性** - 网络波动可能导致断连,需通过 **心跳检测**(定时发送 Ping/Pong 帧)自动重连。 3. **安全性** - 使用 `wss://` 协议(WebSocket over TLS)加密传输,防止数据窃听。 --- ### 七、对比其他实时通信技术 | 技术 | 协议 | 实时性 | 开销 | 适用场景 | |-----------------|---------|--------|-------|------------------------| | **WebSocket** | TCP ||| 双向高频交互 | | **SSE** | HTTP ||| 服务器单向推送(如新闻)| | **长轮询** | HTTP ||| 兼容性要求高的简单场景 | --- ### 总结 WebSocket 是构建 **实时双向通信** 应用的基石技术,适合需要快速响应、高频数据交换的场景。结合现代框架(如 Spring WebSocket、Socket.IO)和浏览器 API,开发者可轻松实现聊天室、实时监控等复杂功能。若需兼容老旧设备,可搭配降级方案(如轮询)确保用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值