WebSocket 与 SSE 深度解析:从原理到面试实战

5 阅读5分钟

在实时通信成为前端高频需求的今天(聊天应用、AI 流式输出、实时通知等),WebSocket 和 SSE(Server-Sent Events)几乎是面试中的必考点。

这篇文章不仅帮你理解两者的本质区别,还会结合实际项目(如聊天系统、LLM 流式输出)讲清楚什么时候该用谁,以及面试该怎么讲


一、为什么需要 WebSocket / SSE?

我们先从 HTTP 说起。

HTTP 是一种请求-响应模型

  • 客户端发起请求
  • 服务端返回响应
  • 连接结束(短连接)

问题在于:

如果服务端有“新数据”,无法主动推送给客户端。

比如:

  • 聊天应用:别人发消息了
  • 股票行情:价格变化
  • AI 输出:模型逐字返回内容

如果继续用 HTTP,只能这样做:

1. 轮询(Polling)

setInterval(() => {
  fetch('/messages')
}, 2000)

问题:

  • 延迟高(取决于轮询间隔)
  • 浪费资源(大量无效请求)
  • 服务端压力大

这就是 WebSocket 和 SSE 出现的背景。


二、WebSocket:真正的双向实时通信

2.1 什么是 WebSocket?

WebSocket 是 HTML5 提供的一种协议:

在浏览器和服务器之间建立一个持久化的双向通信通道

关键点:

  • 基于 TCP
  • 全双工通信(双向)
  • 一次连接,持续通信

2.2 建立连接过程

WebSocket 并不是一开始就是 ws 协议,而是:

  1. 先通过 HTTP 发起请求
  2. 服务端返回:
101 Switching Protocols
  1. 协议升级为 WebSocket

这一步叫:协议升级(Upgrade)


2.3 通信特点

  • 客户端可以主动发
  • 服务端可以主动推
  • 支持文本 / 二进制
const ws = new WebSocket('ws://localhost:3000/ws')

ws.onmessage = (event) => {
  console.log(event.data)
}

ws.send('hello')

2.4 适用场景

WebSocket 适用于:

  • 聊天系统(IM)
  • 在线游戏
  • 实时协作(文档编辑)
  • 多人同步场景

因为这些场景都需要:

客户端和服务端都能随时发消息


三、SSE:为“服务端推送”而生

3.1 什么是 SSE?

SSE(Server-Sent Events)是基于 HTTP 的一种技术:

服务端可以持续不断地向客户端推送数据

特点:

  • 单向通信(只能服务端 → 客户端)
  • 基于 HTTP
  • 使用 text/event-stream

3.2 使用方式

前端:

const eventSource = new EventSource('/api/stream')

etSource.onmessage = (event) => {
  console.log(event.data)
}

后端:

res.setHeader('Content-Type', 'text/event-stream')
res.write('data: hello\n\n')

3.3 核心特点

  • 长连接(不会关闭)
  • 自动重连
  • 轻量级
  • 仅支持文本(通常 JSON)

3.4 适用场景

SSE 非常适合:

AI 流式输出

比如 ChatGPT:

  • 用户发送一次 prompt
  • 服务端不断返回 token

完全符合:

一次请求 + 多次返回(单向流)


四、WebSocket vs SSE 核心区别

可以从 5 个维度对比(面试直接用):

4.1 通信方式

  • HTTP / SSE:单向
  • WebSocket:双向

这是最核心区别


4.2 协议

  • SSE:基于 HTTP(text/event-stream)
  • WebSocket:独立协议(ws / wss)

4.3 数据格式

  • SSE:文本
  • WebSocket:文本 + 二进制

4.4 使用复杂度

  • SSE:简单
  • WebSocket:复杂(连接管理、状态维护)

4.5 典型场景

技术场景
WebSocket聊天、游戏、协作
SSEAI 流式输出、通知

五、为什么聊天用 WebSocket,而不是 SSE?

这是一个面试“加分问题”。

聊天的本质需求:

  • 用户要发消息(客户端 → 服务端)
  • 用户要收消息(服务端 → 客户端)

双向通信

而 SSE:

  • 只能服务端推送
  • 客户端发消息仍需 HTTP

结果:

会变成:SSE + HTTP 混合方案(复杂且低效)

所以聊天必须用 WebSocket。


六、心跳机制

6.1 为什么需要?

因为 WebSocket / SSE 都是长连接:

可能出现:

  • 网络断开
  • 客户端掉线
  • 连接假死

必须检测连接是否还活着。


6.2 实现原理

核心三步:

1️⃣ 定时发送 ping

setInterval(() => {
  ws.send(JSON.stringify({ type: 'ping' }))
}, 30000)

2️⃣ 服务端返回 pong

if (msg.type === 'ping') {
  ws.send(JSON.stringify({ type: 'pong' }))
}

3️⃣ 超时重连

  • 如果没收到 pong
  • 认为连接断开
  • 触发重连逻辑

6.3 类比理解

可以这样说:

就像两个人打电话,会 periodically 问一句“你还在吗?”


七、HTTP vs WebSocket vs SSE 总结

特性HTTPSSEWebSocket
通信方式单向单向双向
连接短连接长连接长连接
实时性非常好
数据格式任意文本文本/二进制
场景普通请求流式输出实时通信

八、面试标准回答模板

如果面试官问:WebSocket 和 SSE 有什么区别?

你可以这样回答:

WebSocket 和 SSE 都可以实现服务端向客户端的实时推送,但两者有本质区别。

第一,通信方式不同:WebSocket 是全双工通信,客户端和服务端都可以主动发送消息;而 SSE 是单向通信,只能由服务端向客户端推送。

第二,协议不同:WebSocket 是独立协议,通过 HTTP Upgrade 升级;而 SSE 本质上还是 HTTP,使用 text/event-stream。

第三,使用场景不同:WebSocket 更适合聊天、游戏这类需要双向通信的场景;而 SSE 更适合像 AI 流式输出这种“请求一次,持续返回”的场景。

在实际项目中,我在做聊天系统时使用 WebSocket 来实现消息的实时收发和广播,而在对接大模型接口时使用 SSE 来实现流式输出,这样可以降低实现复杂度。


九、总结

一句话总结:

WebSocket 解决“实时双向通信”,SSE 解决“服务端持续推送”。

如果你是在做:

  • 聊天系统 → WebSocket
  • AI 输出 → SSE

基本不会选错。