PIDtoolbox完全指南:如何用3步轻松解决无人机飞行不稳定问题
2026/6/21 14:32:07
长连接指客户端与服务端建立连接后,在较长时间内保持不关闭,用于多次通信或持续数据流传输。
核心目标:
从通信层级来看,Python 的长连接可以分为:
| 层级 | 技术 |
|---|---|
| HTTP 层 | Keep-Alive / SSE |
| 应用协议层 | WebSocket |
| 传输层 | TCP Socket |
| 异步模型 | asyncio / uvloop |
| 消息系统 | Redis Pub/Sub 等 |
下面逐一展开。
HTTP/1.1 默认开启Connection: keep-alive
同一个 TCP 连接可复用多次 HTTP 请求。
⚠️ 注意:
HTTP 长连接 ≠ 实时通信
它只是“连接复用”,不是推送模型。
importrequests session=requests.Session()foriinrange(10):resp=session.get("http://localhost:8000/health")print(resp.status_code)session.close()Session内部维护连接池优点
缺点
keepalive_timeoutWebSocket 基于 HTTP 握手升级协议:
HTTP → Upgrade → WebSocket特点:
fromfastapiimportFastAPI,WebSocketimportasyncio app=FastAPI()@app.websocket("/ws")asyncdefwebsocket_endpoint(ws:WebSocket):awaitws.accept()try:whileTrue:data=awaitws.receive_text()awaitws.send_text(f"echo:{data}")exceptException:awaitws.close()importasyncioimportwebsocketsasyncdeftest_ws():asyncwithwebsockets.connect("ws://localhost:8000/ws")asws:awaitws.send("hello")resp=awaitws.recv()print(resp)asyncio.run(test_ws())优点
缺点
proxy_read_timeouttext/event-streamfromfastapiimportFastAPIfromfastapi.responsesimportStreamingResponseimporttime app=FastAPI()defevent_generator():foriinrange(5):yieldf"data: message{i}\n\n"time.sleep(1)@app.get("/sse")defsse():returnStreamingResponse(event_generator(),media_type="text/event-stream")importrequests resp=requests.get("http://localhost:8000/sse",stream=True)forlineinresp.iter_lines():ifline:print(line.decode())优点
缺点
importasyncioasyncdefhandle(reader,writer):whileTrue:data=awaitreader.read(1024)ifnotdata:breakwriter.write(data)awaitwriter.drain()asyncio.run(asyncio.start_server(handle,"0.0.0.0",9000))importasyncioasyncdefclient():reader,writer=awaitasyncio.open_connection("127.0.0.1",9000)writer.write(b"ping")awaitwriter.drain()data=awaitreader.read(1024)print(data)writer.close()asyncio.run(client())importasyncioimportuvloop asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())结论:
生产级长连接,几乎必用 asyncio
importredis r=redis.Redis()pubsub=r.pubsub()pubsub.subscribe("events")formsginpubsub.listen():print(msg)whileTrue:ws.send("ping")time.sleep(30)asyncdefrun(n=1000):tasks=[test_ws()for_inrange(n)]awaitasyncio.gather(*tasks)✅ 实时
✅ 高频交互
✅ 流式输出
❌ 请求极少
❌ LB 无法保持会话
❌ 资源极度受限
| 技术 | 通信模型 | 推送 | 并发 | 复杂度 | 推荐 |
|---|---|---|---|---|---|
| HTTP Keep-Alive | 请求/响应 | ❌ | 高 | 低 | ⭐⭐⭐ |
| WebSocket | 全双工 | ✅ | 高 | 中 | ⭐⭐⭐⭐⭐ |
| SSE | 单向流 | ✅ | 中 | 低 | ⭐⭐⭐⭐ |
| TCP Socket | 自定义 | ✅ | 极高 | 高 | ⭐⭐⭐ |
| Redis Pub/Sub | 消息 | 间接 | 高 | 中 | ⭐⭐⭐⭐ |
**Python 生产级长连接首选:
asyncio + WebSocket(或 SSE)
TCP 仅在极致性能或特殊协议下使用