WebSocket:浏览器里的双向通信

B站影视 港台电影 2025-04-08 23:00 2

摘要:WebSocket 是一种基于 TCP 的全双工通信协议,设计目的是化解传统 HTTP 协议于实时通信方面的局限性。它通过于客户端和服务器之间构建持久化的连接,准许双方随时主动传送数据,规避了 HTTP 轮询所导致的延迟以及资源浪费。WebSocket 连接以

WebSocket

WebSocket 是一种基于 TCP 的全双工通信协议,设计目的是化解传统 HTTP 协议于实时通信方面的局限性。它通过于客户端和服务器之间构建持久化的连接,准许双方随时主动传送数据,规避了 HTTP 轮询所导致的延迟以及资源浪费。WebSocket 连接以 HTTP 握手起始(状态码 101 切换协议),其后升级为二进制帧传输,极大地削减了通信开销。其核心特质涵盖低延迟、高效率以及真正的双向通信能力,适用于需求实时数据交换的场景。

WebSocket与普通HTTP请求的对比

(上图源于 The Road to WebSockets | WebSocket.org 。)

WebSocket 的标准化进程发端于 2011 年发布的 RFC 6455,当下已成为 HTML5 规范的关键构成部分。WebSocket 支持文本和二进制数据的传输,内置心跳机制(Ping/Pong 帧)以维持连接的活性,并且能够通过子协议扩展功能(诸如 STOMP)。在安全方面,强制力荐 TLS 加密(wss://),同时维系与 HTTP 相同的端口兼容性,保证穿透防火墙的能力。现代所有主流的浏览器和服务器框架(例如 Node.js、Spring、Django)皆提供原生支持。

WebSocket 已被广泛运用于在线聊天、金融行情推送、多人在线游戏、协同编辑等实时系统。相较于后续涌现的 SSE(Server-Sent Events)和 WebTransport 等技术,它在成熟度、兼容性以及灵活性上依旧占据优势。伴随物联网和边缘计算的发展,WebSocket 持续在设备实时监控、智能家居等领域发挥着关键作用,成为现代 Web 实时通信的基础设施层级的技术。

下面是基于 FastAPI 的一个协程版 server.py 代码示例,还附带了一个测试用的前端界面。

# /// script# requires-python = ">=3.12"# dependencies = [# "fastapi",# "uvicorn",# "websockets",# ]# ///from fastapi import FastAPI, WebSocket, WebSocketDisconnectfrom fastapi.responses import HTMLResponseapp = FastAPI# 存储活跃的 WebSocket 连接active_connections = set# WebSocket 路由@app.websocket("/ws")async def websocket_endpoint(websocket: WebSocket):await websocket.accept # 接受 WebSocket 连接active_connections.add(websocket) # 存储连接try:while True:data = await websocket.receive_text # 接收客户端消息print(f"Received: {data}")# 广播消息给所有连接的客户端for connection in active_connections:await connection.send_text(f"Server Echo: {data}")except WebSocketDisconnect:print("Client disconnected")finally:active_connections.remove(websocket) # 移除断开连接# 以上是一个比较完整的服务端示例代码,返回服务端发送的数据。# ======== ======== ======== ========# 以下是一个简单的前端页面。用于测试,并非必须。html = """WebSocket Test

FastAPI WebSocket Demo

Sendconst ws = new WebSocket("ws://localhost:8000/ws");ws.onmessage = function(event) {const messages = document.getElementById('messages');const message = document.createElement('li');message.textContent = event.data;messages.appendChild(message);};function sendMessage(event) {event.preventDefault;const input = document.getElementById("messageText");ws.send(input.value);input.value = '';}"""@app.get("/")async def get:return HTMLResponse(html)if __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000)

以上代码,可以用 uv 来运行:

$ uv run server.pyINFO: Started server process INFO: Waiting for application startup.INFO: Application startup complete.INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

调试页面运行结果

在之前的调试网页 http://localhost:8000 中,打开调试控制台,可以直接使用以下的极简 JavaScript 代码,完整调用并查看效果。

const client = new WebSocket("ws://localhost:8000/ws");client.onmessage = function(event) {console.log(event.data);};

控制台直接运行结果

此外,还可使用各种浏览器插件,进行 WebSocket 调试,比如 PieSocket WebSocket Tester 之类的。

虽然 WebSocket 一般只用于浏览器。但有时为了兼容和节省开发成本,也可能会有其它类型的客户端。

#!/usr/bin/env -S uv run# /// script# requires-python = ">=3.12"# dependencies = [# "websockets",# ]# ///import asyncioimport websocketsasync def websocket_client:# 连接 FastAPI 的 WebSocket 服务端uri = "ws://localhost:8000/ws"async with websockets.connect(uri) as websocket:print("Connected to server.")# 异步接收服务器消息async def receive_messages:while message := await websocket.recv:print(f"[Server]: {message}")async def send(msg):print("[Client]:", msg)await websocket.send(msg)await asyncio.sleep(0.1)# 启动接收协程receive_task = asyncio.create_task(receive_messages)# 发送测试用的信息await send("hello")await send("world")await send("1")await send("2")receive_task.cancel # 关闭接收协程print("Disconnected from server.")if __name__ == "__main__":asyncio.run(websocket_client)

以上是 client.py 示例。用 uv 可以运行,配合前面的服务端,可以得到以下结果:

$ uv run client.py Connected to server.[Client]: hello[Server]: Server Echo: hello[Client]: world[Server]: Server Echo: world[Client]: 1[Server]: Server Echo: 1[Client]: 2[Server]: Server Echo: 2Disconnected from server.

WebSocket 技术的发展历程能够追溯至互联网对于实时通信需求的与日俱增。在早期的 Web 应用里,HTTP 协议鉴于设计上的局限(例如无状态、半双工通信),难以契合实时数据推送的需求。开发者起初运用轮询(Polling)和长轮询(Long Polling)等权宜之计,然而这些方式效率欠佳,会引发大量无效请求以及延迟的问题。2008 年,WebSocket 的概念首度被提出,旨在化解传统 HTTP 在双向通信方面的缺陷,其核心要义在于通过单一的 TCP 连接达成全双工通信,降低握手的耗费以及带宽的浪费。

2011 年,WebSocket 协议被 IETF 规范为 RFC 6455,这意味着它正式成为 Web 实时通信的主流化解之方。该协议凭借 HTTP Upgrade 机制构建连接,在握手成功之后,客户端与服务器能够于同一连接之上自如地交互数据帧,极大地增强了实时性与效率。同年,主流的浏览器,诸如 Chrome、Firefox 开始对 WebSocket 予以支持,有力地促进了其在在线聊天、股票行情、游戏等场景中的广泛运用。

WebSocket 的演进进程与 Web 2.0 的发展态势紧密相连。在 Web 1.0 时期,静态页面仅需进行单向的数据展示,然而 Web 2.0 中的交互式应用(诸如社交网络、协同编辑等)催生出了双向通信的需求。相较于早期的 Comet 技术(基于 HTTP 长连接),WebSocket 规避了连接阻塞以及资源浪费的问题,成为了更为高效的替代之选。此外,它的兼容性设计(例如默认使用 80/443 端口)令其能够穿透防火墙,适应繁杂的网络环境。

随着 HTML5 的广泛普及,WebSocket 被纳入到其核心技术体系之中,进一步助推了标准化的进程。在协议优化层面,引入了 Ping/Pong 帧以用于连接的保活,并且支持子协议扩展(例如 STOMP),增强了其灵活性与功能性。在安全性方面,WebSocket 默认为推荐使用 WSS(WebSocket Secure),通过 TLS 加密来保障数据传输的安全。

近些年来,WebSocket 已然成为实时 Web 应用的基础所在,支撑着诸如直播弹幕、在线协作、IoT 设备监控等场景。尽管诸如 WebTransport(基于 QUIC)之类的新兴技术正在探寻更低延迟的通信方式,WebSocket 凭借自身的成熟程度和广泛的支持,依旧在实时通信领域占据着主导地位。在未来,伴随 Web3.0 和边缘计算的发展,WebSocket 或许会进一步得到优化,从而适应更为复杂的分布式实时交互需求。

来源:界世看眼睁

相关推荐