核心概念总结
📅 2026/7/7 7:20:39
👁️ 阅读次数
📝 编程学习
async/await 异步编程
# 同步(阻塞) def function(): result = blocking_operation() # 必须等待完成 return result # 异步(非阻塞) async def function(): result = await async_operation() # 等待但不阻塞其他任务 return result作用:
- 一个程序可以同时处理多个任务
- 服务端可以同时处理多个客户端
- 客户端可以同时收发消息
2. WebSocket 核心 API
| API | 说明 | 示例 |
|---|---|---|
websockets.serve(handler, host, port) | 启动服务端 | 服务端使用 |
websockets.connect(uri) | 连接服务端 | 客户端使用 |
await websocket.send(msg) | 发送消息 | 双方都可用 |
await websocket.recv() | 接收一条消息(阻塞) | 双方都可用 |
async for msg in websocket | 持续接收消息(循环) | 双方都可用 |
3. 通信模式对比
| 模式 | 特点 | 适用场景 | 代码示例 |
|---|---|---|---|
| 请求-响应 | 客户端问,服务端答 | 查询类操作 | simple_server.py |
| 服务端推送 | 服务端主动发消息 | 通知、实时数据 | push_server.py |
| 全双工 | 双方随时收发 | 聊天、游戏 | push_client.py |
4. asyncio.gather() 并发执行
# 同时运行多个异步任务 await asyncio.gather( task1(), # 任务 1 task2(), # 任务 2 task3() # 任务 3 ) # 所有任务并发执行,等待全部完成应用:
- 服务端:同时推送消息 + 接收消息
- 客户端:同时接收推送 + 等待用户输入
回到顶部
实际应用场景
1. 即时聊天应用
# 服务端广播消息给所有客户端 connected_clients = set() async def broadcast(message): await asyncio.gather( *[client.send(message) for client in connected_clients] )2. 股票行情推送
# 服务端定时推送最新价格 async def push_stock_price(websocket): while True: price = get_current_price() await websocket.send(json.dumps({"price": price})) await asyncio.sleep(1)3. 在线游戏同步
# 玩家动作同步给其他玩家 async def sync_player_action(action): for player in other_players: await player.websocket.send(action)4. 协作编辑
# 用户编辑时,推送给其他用户 async def on_document_change(change): for user in connected_users: await user.websocket.send(change)回到顶部
HTTP vs WebSocket
| 对比项 | HTTP | WebSocket |
|---|---|---|
| 连接方式 | 短连接(请求-响应) | 长连接(持久化) |
| 通信方向 | 单向(客户端 → 服务端) | 双向(双方互发) |
| 服务端推送 | ❌ 不支持(需轮询) | ✅ 支持 |
| 实时性 | 低(轮询延迟) | 高(实时推送) |
| 带宽占用 | 高(重复请求头) | 低(保持连接) |
| 适用场景 | RESTful API、网页浏览 | 聊天、游戏、实时数据 |
HTTP 轮询示例(低效)
# 客户端每秒轮询一次 while True: response = requests.get("http://server/messages") if response.json()["has_new"]: print("有新消息") time.sleep(1) # 浪费带宽和资源WebSocket 推送(高效)
# 有消息时服务端主动推送 async for message in websocket: print("收到新消息:", message)回到顶部
常见问题
Q1: 为什么要用 async/await?
A:WebSocket 需要同时处理多个连接和消息,异步编程可以高效利用资源。
# 同步代码:一次只能处理一个客户端 def handle_client(websocket): for message in websocket: # 阻塞在这里 send_reply(message) # 异步代码:可以同时处理多个客户端 async def handle_client(websocket): async for message in websocket: # 不阻塞其他客户端 await send_reply(message)Q2: 客户端必须等待服务端回复吗?
A:不是必须的,这取决于你的业务需求。
- 需要等待回复:查询类操作(发送请求,等待结果)
- 不需要等待:发送日志、打点数据(发完就不管)
- 同时收发:聊天、游戏(全双工通信)
Q3: WebSocket 安全吗?
A:WebSocket 支持加密连接(wss://),就像 HTTPS。
# 未加密 uri = "ws://localhost:8765" # 加密(需要 SSL 证书) uri = "wss://example.com:8765"Q4: 如何处理断线重连?
async def connect_with_retry(): while True: try: async with websockets.connect(uri) as websocket: await handle_messages(websocket) except Exception as e: print("连接断开,3 秒后重连...") await asyncio.sleep(3)回到顶部
快速参考
启动顺序
# 1. 先启动服务端 python simple_server.py # 或 push_server.py # 2. 再启动客户端 python simple_client.py # 或 push_client.py修改推送间隔
# push_server.py 第 31 行 await asyncio.sleep(3) # 改成 1 就是 1 秒推送一次修改端口
# 服务端 websockets.serve(handle_client, "localhost", 8765) # 改端口 # 客户端 uri = "ws://localhost:8765" # 改成对应端口回到顶部
总结
通过这两个示例,你已经掌握了:
✅ WebSocket 的基本原理
✅ 客户端发送、服务端响应(simple)
✅ 服务端主动推送(push)
✅ 全双工通信(同时收发)
✅ 异步编程的核心概念
编程学习
技术分享
实战经验