在现代 Web 开发中,实时通信需求越来越多,比如聊天应用、实时通知、直播弹幕、股票行情推送等。实现这些需求的常见技术有 WebSocket 和 SSE(Server-Sent Events),但它们各有优缺点,适用于不同的场景。
本文将详细介绍 WebSocket 和 SSE,并进行对比分析,帮助你选择合适的技术方案。
WebSocket 是 HTML5 引入的全双工通信协议,允许客户端和服务器之间保持持久连接,实现低延迟的双向通信。
Upgrade: websocket
协商,建立 WebSocket 连接。 在线聊天应用(如 IM)
实时游戏(如在线对战)
股票行情推送
直播弹幕
SSE 是基于 HTTP 的服务器推送技术,允许服务器主动向客户端发送数据,但客户端无法主动向服务器发送消息。
EventSource
监听服务器的推送数据。EventSource
组件自带断线重连功能。 新闻或社交媒体的实时更新
服务器通知推送(如系统消息)
监控数据流(如服务器日志监控)
特性 | WebSocket | SSE(Server-Sent Events) |
---|---|---|
通信模式 | 双向通信 | 单向(服务器 → 客户端) |
协议 | 独立协议(ws/wss) | HTTP(基于 HTTP/1.1 长连接) |
数据格式 | 文本 & 二进制 | 仅支持文本(UTF-8) |
连接方式 | 需升级 HTTP 连接 | 直接使用 HTTP 长连接 |
自动重连 | 需要手动实现 | EventSource 自带重连 |
浏览器支持 | 现代浏览器都支持 | 现代浏览器支持(IE 不支持) |
适用场景 | 聊天、游戏、实时数据同步 | 新闻推送、状态更新 |
from fastapi import FastAPI, WebSocket
app = FastAPI()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"你发送了: {data}")
const socket = new WebSocket("ws://localhost:8000/ws");
socket.onopen = () => {
console.log("WebSocket 连接已建立");
socket.send("Hello Server");
};
socket.onmessage = (event) => {
console.log("收到消息: ", event.data);
};
from fastapi import FastAPI
from starlette.responses import StreamingResponse
import asyncio
app = FastAPI()
async def event_generator():
while True:
yield f"data: {await asyncio.sleep(1, result='Hello, SSE!')}
"
@app.get("/events")
async def sse_endpoint():
return StreamingResponse(event_generator(), media_type="text/event-stream")
const eventSource = new EventSource("http://localhost:8000/events");
eventSource.onmessage = (event) => {
console.log("收到推送: ", event.data);
};
eventSource.onerror = () => {
console.log("SSE 连接异常");
};
如果你的应用需要实时通信,并且只需要服务器推送数据,SSE 是更简单的选择。但如果你需要双向交互或二进制数据支持,WebSocket 更合适。