Python实现长连接的多种方式解析

 更新时间:2025年12月18日 08:44:49   作者:破烂pan  
本文介绍了Python实现长连接的多种方式,包括HTTP长连接、WebSocket、Server-Sent Events、TCPSocket、异步长连接模型和消息系统模拟长连接,每种方式都有其适用场景和优缺点,并提供了示例代码和生产注意事项,需要的朋友可以参考下

一、什么是“长连接”(Long-lived Connection)

长连接指客户端与服务端建立连接后,在较长时间内保持不关闭,用于多次通信或持续数据流传输。

核心目标:

  • 降低频繁建连/断连的开销(TCP / TLS)
  • 实现实时通信、流式数据、推送能力
  • 支撑高并发、低延迟业务场景

二、Python 实现长连接的主流方式总览

通信层级 来看,Python 的长连接可以分为:

层级技术
HTTP 层Keep-Alive / SSE
应用协议层WebSocket
传输层TCP Socket
异步模型asyncio / uvloop
消息系统Redis Pub/Sub 等

下面逐一展开。

三、HTTP 长连接(Keep-Alive)

1. 原理说明

HTTP/1.1 默认开启 Connection: keep-alive
同一个 TCP 连接可复用多次 HTTP 请求。

注意:
HTTP 长连接 ≠ 实时通信
它只是“连接复用”,不是推送模型。

2. 适用场景

  • 内部 API 调用
  • 微服务间 RPC
  • 高频短请求(如模型推理接口)

3. 示例代码(requests + Session)

import requests

session = requests.Session()

for i in range(10):
    resp = session.get("http://localhost:8000/health")
    print(resp.status_code)

session.close()

原理点

  • Session 内部维护连接池
  • 复用 TCP 连接,减少握手开销

4. 优缺点分析

优点

  • 实现简单
  • 与现有 HTTP 服务完全兼容

缺点

  • 不支持服务端主动推送
  • 连接空闲易被 LB / Nginx 断开

5. 生产注意事项

  • Nginx keepalive_timeout
  • 服务端最大连接数
  • 不适合实时推送类业务

四、WebSocket(全双工长连接)

1. 原理说明

WebSocket 基于 HTTP 握手升级协议:

HTTP → Upgrade → WebSocket

特点:

  • 全双工
  • 服务端可主动推送
  • 一个连接可持续通信

2. 典型使用场景

  • 实时消息 / IM
  • 模型流式输出(Token Streaming)
  • 实时监控面板
  • 在线协作

3. FastAPI WebSocket 示例

服务端

from fastapi import FastAPI, WebSocket
import asyncio

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(ws: WebSocket):
    await ws.accept()
    try:
        while True:
            data = await ws.receive_text()
            await ws.send_text(f"echo: {data}")
    except Exception:
        await ws.close()

客户端测试脚本

import asyncio
import websockets

async def test_ws():
    async with websockets.connect("ws://localhost:8000/ws") as ws:
        await ws.send("hello")
        resp = await ws.recv()
        print(resp)

asyncio.run(test_ws())

4. 优缺点分析

优点

  • 真正的实时通信
  • 支持流式数据

缺点

  • 状态连接,消耗资源
  • LB 场景需粘性会话

5. 生产级注意事项

  • 心跳(ping/pong)
  • 最大连接数控制
  • Nginx proxy_read_timeout
  • Kubernetes 下需 Session Affinity

五、Server-Sent Events(SSE)

1. 原理说明

  • 基于 HTTP
  • 单向:服务端 → 客户端
  • 使用 text/event-stream

2. 适用场景

  • 实时通知
  • 日志流
  • AI 模型流式输出(无双向需求)

3. FastAPI SSE 示例

服务端

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import time

app = FastAPI()

def event_generator():
    for i in range(5):
        yield f"data: message {i}\n\n"
        time.sleep(1)

@app.get("/sse")
def sse():
    return StreamingResponse(event_generator(),
                             media_type="text/event-stream")

客户端测试脚本

import requests

resp = requests.get("http://localhost:8000/sse", stream=True)
for line in resp.iter_lines():
    if line:
        print(line.decode())

4. 优缺点

优点

  • 比 WebSocket 简单
  • HTTP 原生,穿透性好

缺点

  • 单向通信
  • 浏览器连接数限制

六、TCP Socket 长连接(底层方案)

1. 原理说明

  • 直接基于 TCP
  • 自定义协议
  • 需自行处理粘包、心跳、重连

2. asyncio TCP 示例

服务端

import asyncio

async def handle(reader, writer):
    while True:
        data = await reader.read(1024)
        if not data:
            break
        writer.write(data)
        await writer.drain()

asyncio.run(asyncio.start_server(handle, "0.0.0.0", 9000))

客户端

import asyncio

async def client():
    reader, writer = await asyncio.open_connection("127.0.0.1", 9000)
    writer.write(b"ping")
    await writer.drain()
    data = await reader.read(1024)
    print(data)
    writer.close()

asyncio.run(client())

3. 适用场景

  • 游戏服务器
  • 自定义高性能协议
  • 内部 RPC

4. 风险点

  • 实现成本高
  • 协议设计复杂
  • 调试困难

七、异步长连接模型(asyncio / uvloop)

核心价值

  • 单线程支撑万级连接
  • IO 多路复用(epoll)
import asyncio
import uvloop

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

结论
生产级长连接,几乎必用 asyncio

八、消息系统模拟“长连接”

Redis Pub/Sub 示例

import redis

r = redis.Redis()

pubsub = r.pubsub()
pubsub.subscribe("events")

for msg in pubsub.listen():
    print(msg)

特点

  • 解耦
  • 非真实 TCP 长连接
  • 更适合集群广播

九、Python 如何测试长连接(重点)

1. 长时间保持连接

while True:
    ws.send("ping")
    time.sleep(30)

2. 心跳机制

  • WebSocket ping/pong
  • TCP 自定义 heartbeat
  • 超时主动关闭

3. 并发测试(asyncio)

async def run(n=1000):
    tasks = [test_ws() for _ in range(n)]
    await asyncio.gather(*tasks)

十、生产级最佳实践总结

什么时候用长连接?

✅ 实时
✅ 高频交互
✅ 流式输出

什么时候不用?

❌ 请求极少
❌ LB 无法保持会话
❌ 资源极度受限

十一、方案对比表

技术通信模型推送并发复杂度推荐
HTTP Keep-Alive请求/响应⭐⭐⭐
WebSocket全双工⭐⭐⭐⭐⭐
SSE单向流⭐⭐⭐⭐
TCP Socket自定义极高⭐⭐⭐
Redis Pub/Sub消息间接⭐⭐⭐⭐

十二、最终结论

**Python 生产级长连接首选:
asyncio + WebSocket(或 SSE)
TCP 仅在极致性能或特殊协议下使用

以上就是Python实现长连接的多种方式解析的详细内容,更多关于Python实现长连接的资料请关注脚本之家其它相关文章!

相关文章

  • Pygame游戏开发之太空射击实战精灵的使用上篇

    Pygame游戏开发之太空射击实战精灵的使用上篇

    相信大多数8090后都玩过太空射击游戏,在过去游戏不多的年代太空射击自然属于经典好玩的一款了,今天我们来自己动手实现它,在编写学习中回顾过往展望未来,下面开始讲解精灵的使用
    2022-08-08
  • python文件名和文件路径操作实例

    python文件名和文件路径操作实例

    下面小编就为大家带来一篇python文件名和文件路径操作实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • pytest参数化:@pytest.mark.parametrize详解

    pytest参数化:@pytest.mark.parametrize详解

    pytest.mark.parametrize装饰器能够对测试函数进行参数化处理,使得一个测试函数可以用多组数据执行多次,这有助于检查不同输入下的期望输出是否匹配,提高测试的效率和覆盖率,装饰器可以应用于函数、模块或类,支持多个装饰器组合使用,增强测试的灵活性和综合性
    2024-10-10
  • DES加密解密算法之python实现版(图文并茂)

    DES加密解密算法之python实现版(图文并茂)

    这篇文章主要介绍了DES加密解密算法之python实现版,图文并茂的为大家分享一下,需要的朋友可以参考下
    2018-12-12
  • python 保存float类型的小数的位数方法

    python 保存float类型的小数的位数方法

    今天小编就为大家分享一篇python 保存float类型的小数的位数方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • PyCharm如何设置新建文件默认为LF换行符

    PyCharm如何设置新建文件默认为LF换行符

    这篇文章主要介绍了PyCharm如何设置新建文件默认为LF换行符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • python中安装模块包版本冲突问题的解决

    python中安装模块包版本冲突问题的解决

    这篇文章主要给大家介绍了在python中安装模块包版本冲突问题的解决方法,文中介绍了该问题的原因与解决方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-05-05
  • 情人节快乐! python绘制漂亮玫瑰

    情人节快乐! python绘制漂亮玫瑰

    情人节快乐! 这篇文章主要教大家如何用python绘制漂亮玫瑰花,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Python函数参数和注解的使用

    Python函数参数和注解的使用

    本文介绍了Python函数的四种参数:定位参数、可变参数、默认值参数、关键字参数,和第五种Python3新特性参数:仅限关键字参数。函数注解是一种元数据,存在__annotations__属性中,备注函数的参数和返回值的类型,它只是个注解,Python不会做任何强制检查。
    2021-06-06
  • Python安装OpenCV的示例代码

    Python安装OpenCV的示例代码

    这篇文章主要介绍了Python安装OpenCV的示例代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03

最新评论