agentic_huge_data_base / wiki
页面 Open WebUI · 15.1 WebSocket 架构·DeepWiki 中文全文译文

15.1 · WebSocket 架构(WebSocket Architecture)

多模型对话工作台与知识应用入口 · 本章是 Open WebUI DeepWiki 中文译文的独立章节页,保留原始链接、源码锚点、模块标签和章节层级。

项目Open WebUI 章节15.1 状态全文译文 模块认证、权限与安全、工具、记忆与模型调用、接口与服务契约、界面与交互
源码线索
  • backend/open_webui/socket/main.py
  • backend/open_webui/socket/utils.py
  • backend/open_webui/tasks.py
  • backend/open_webui/test/util/test_redis.py
  • backend/open_webui/utils/rate_limit.py
  • backend/open_webui/utils/redis.py
  • backend/open_webui/utils/auth.py
  • backend/open_webui/env.py
模块标签
  • 认证、权限与安全
  • 工具、记忆与模型调用
  • 接口与服务契约
  • 界面与交互
  • 频道、笔记与协作

中文译文

WebSocket 架构(中文译文)

原始 DeepWiki 页面:https://deepwiki.com/open-webui/open-webui/15.1-websocket-architecture
翻译时间:2026-06-09T16:11:37.621Z
翻译模型:deepseek-chat
原文字符数:10338
项目:Open WebUI (open-webui)

---

WebSocket 架构

相关源文件

以下文件为本 wiki 页面的生成上下文:

  • backend/open_webui/socket/main.py
  • backend/open_webui/socket/utils.py
  • backend/open_webui/tasks.py
  • backend/open_webui/test/util/test_redis.py
  • backend/open_webui/utils/rate_limit.py
  • backend/open_webui/utils/redis.py

目的与范围

本文档介绍 Open WebUI 中基于 Socket.IO 的 WebSocket 服务器架构,涵盖服务器配置、连接生命周期、认证、房间管理及事件路由模式。WebSocket 层支持实时功能,包括 AI 响应流式传输、协同文档编辑(Yjs)、带输入状态提示的频道消息以及任务进度更新。

---

Socket.IO 服务器初始化

服务器配置

Socket.IO 服务器在 backend/open_webui/socket/main.py backend/open_webui/socket/main.py:1-98 中初始化,支持 WebSocket 和 HTTP 长轮询两种传输方式。服务器可独立运行,也可通过 AsyncRedisManager backend/open_webui/socket/main.py:65-84 使用 Redis 支持多实例部署。

标准服务器配置:

backend/open_webui/socket/main.py:86-96

sio = socketio.AsyncServer(
    cors_allowed_origins=SOCKETIO_CORS_ORIGINS,
    async_mode='asgi',
    transports=(['websocket'] if ENABLE_WEBSOCKET_SUPPORT else ['polling']),
    allow_upgrades=ENABLE_WEBSOCKET_SUPPORT,
    always_connect=True,
    logger=WEBSOCKET_SERVER_LOGGING,
    ping_interval=WEBSOCKET_SERVER_PING_INTERVAL,
    ping_timeout=WEBSOCKET_SERVER_PING_TIMEOUT,
    engineio_logger=WEBSOCKET_SERVER_ENGINEIO_LOGGING,
)

基于 Redis 的服务器配置:

backend/open_webui/socket/main.py:65-84

if WEBSOCKET_MANAGER == 'redis':
    if WEBSOCKET_SENTINEL_HOSTS:
        mgr = socketio.AsyncRedisManager(
            get_sentinel_url_from_env(WEBSOCKET_REDIS_URL, WEBSOCKET_SENTINEL_HOSTS, WEBSOCKET_SENTINEL_PORT),
            redis_options=WEBSOCKET_REDIS_OPTIONS,
        )
    else:
        mgr = socketio.AsyncRedisManager(WEBSOCKET_REDIS_URL, redis_options=WEBSOCKET_REDIS_OPTIONS)
    sio = socketio.AsyncServer(
        # ... 同上选项
        client_manager=mgr,
    )
配置参数
参数环境变量用途
transportsENABLE_WEBSOCKET_SUPPORT启用的协议(轮询/WebSocket) backend/open_webui/socket/main.py:76
ping_intervalWEBSOCKET_SERVER_PING_INTERVAL心跳包发送间隔(秒) backend/open_webui/socket/main.py:81
ping_timeoutWEBSOCKET_SERVER_PING_TIMEOUT超时时间(秒) backend/open_webui/socket/main.py:82
client_managerWEBSOCKET_MANAGER多实例 Redis 管理器 backend/open_webui/socket/main.py:65

来源: backend/open_webui/socket/main.py:63-96, backend/open_webui/env.py:25-41

---

认证与会话管理

两阶段认证

Open WebUI 为 Socket.IO 连接实现了两阶段认证模式:

  1. 阶段 1:连接时认证connect 事件) backend/open_webui/socket/main.py:306-327
  2. 阶段 2:用户加入认证user-join 事件) backend/open_webui/socket/main.py:328-363

阶段 1:连接事件 初始 connect 事件处理器使用 decode_token backend/open_webui/utils/auth.py:42 验证 auth 参数中的 JWT 令牌,并填充 SESSION_POOL backend/open_webui/socket/main.py:306-327

阶段 2:用户加入事件 连接后,客户端发送 user-join 事件以完成初始化、加入频道并接收初始用户状态 backend/open_webui/socket/main.py:328-363

会话与使用池

系统维护多个池来跟踪活跃用户及其活动。这些池根据 WEBSOCKET_MANAGER 设置 backend/open_webui/socket/main.py:105-165 可以是本地字典或 RedisDict 实例 backend/open_webui/socket/utils.py:44-123

池名称代码实体用途
SESSION_POOLSESSION_POOLsid 映射到用户元数据 backend/open_webui/socket/main.py:123-128
USAGE_POOLUSAGE_POOL跟踪每个会话的活跃模型使用情况 backend/open_webui/socket/main.py:129-134
MODELSMODELS缓存的模型定义 backend/open_webui/socket/main.py:116-121

会话清理: periodic_session_pool_cleanup 函数 backend/open_webui/socket/main.py:173-194 会清理在 SESSION_POOL_TIMEOUT(120 秒)backend/open_webui/socket/main.py:101 内未发送心跳的孤立会话。

来源: backend/open_webui/socket/main.py:101-165, backend/open_webui/socket/main.py:173-194, backend/open_webui/socket/utils.py:44-123

---

基于房间的事件路由

Socket.IO 房间提供隔离的事件通道。Open WebUI 使用特定的房间命名约定来路由消息:

房间模式代码实现用途
user:{user_id}sio.enter_room(sid, f"user:{user.id}")定向用户事件 backend/open_webui/socket/main.py:325
channel:{channel_id}sio.enter_room(sid, f"channel:{channel.id}")群组消息 backend/open_webui/socket/main.py:361
doc_{document_id}sio.enter_room(sid, f"doc_{document_id}")Yjs 文档编辑 backend/open_webui/socket/main.py:488
事件广播模式

服务器使用多个辅助函数来广播事件:

  • emit_to_users:通过向多个用户的个人房间发送事件来广播 backend/open_webui/socket/main.py:260-274
  • get_event_emitter:创建一个闭包,用于将 AI 响应流式传输到特定用户的房间 backend/open_webui/socket/main.py:718-836
  • get_event_call:使用带超时的 sio.call() 实现请求-响应模式 backend/open_webui/socket/main.py:838-861

来源: backend/open_webui/socket/main.py:260-274, backend/open_webui/socket/main.py:325-361, backend/open_webui/socket/main.py:718-861

---

分布式任务管理

在多节点环境中运行时,任务(如长时间运行的 AI 生成)必须能在实例间管理。系统使用 Redis Pub/Sub 进行分布式任务控制 backend/open_webui/tasks.py:25-42

分布式任务命令流程

graph TD
    subgraph "Node_A_[请求处理器]"
        CT["create_task()"]
        RS["redis_save_task()"]
    end

    subgraph "Redis_后端"
        RTK["REDIS_TASKS_KEY"]
        RPS["REDIS_PUBSUB_CHANNEL"]
    end

    subgraph "Node_B_[任务所有者]"
        RL["redis_task_command_listener()"]
        LT["local_task.cancel()"]
    end

    CT --> RS
    RS --> RTK

    NodeA_Stop["stop_task()"] --> RSC["redis_send_command()"]
    RSC --> RPS
    RPS --> RL
    RL --> LT

关键任务函数:

  • create_task(redis, coroutine, id):生成一个 asyncio.Task 并在 Redis 中注册 backend/open_webui/tasks.py:104-124
  • stop_task(redis, task_id):通过 Redis Pub/Sub 向所有实例发送“停止”命令 backend/open_webui/tasks.py:145-180
  • redis_task_command_listener(app):监听停止命令并取消本地任务 backend/open_webui/tasks.py:25-42

来源: backend/open_webui/tasks.py:20-180

---

Redis 集成与同步

连接管理

get_redis_connection 工具函数 backend/open_webui/utils/redis.py:179-253 提供了一个带缓存的健壮连接工厂,支持:

  • 独立 Redis:通过 REDIS_URL 直接连接。
  • Redis Sentinel:通过 SentinelRedisProxy backend/open_webui/utils/redis.py:33-150 实现自动故障转移的高可用支持。
  • Redis 集群:通过 REDIS_CLUSTER 环境标志 backend/open_webui/env.py:11 实现分布式存储。

Redis 架构抽象

classDiagram
    class SentinelRedisProxy {
        -sentinel: Sentinel
        -service: str
        -_master()
        +__getattr__(item)
    }
    class RedisDict {
        +name: str
        +redis: Redis
        +__setitem__(key, value)
        +__getitem__(key)
    }
    class YdocManager {
        -redis: Redis
        +append_to_updates(doc_id, update)
        -_compact_updates_redis(doc_id)
    }

    SentinelRedisProxy ..> RedisDict : 包装连接
    RedisDict ..> YdocManager : 概念数据存储
    get_redis_connection --* SentinelRedisProxy : 创建

来源: backend/open_webui/utils/redis.py:26-253, backend/open_webui/socket/utils.py:9-228

协同编辑(Yjs)

YdocManager backend/open_webui/socket/utils.py:124-228 使用 pycrdt(Yjs)处理协同文档(笔记)的同步。它支持:

  • 更新缓冲:将二进制更新追加到 Redis 列表 backend/open_webui/socket/utils.py:137-147
  • 滚动压缩:当达到 COMPACTION_THRESHOLD(500)时,将更新压缩为快照以优化性能 backend/open_webui/socket/utils.py:152-166

来源: backend/open_webui/socket/utils.py:124-228

---

速率限制

Open WebUI 包含一个 RateLimiter backend/open_webui/utils/rate_limit.py:6-136,采用滑动窗口策略。它优先使用 Redis 在节点间共享状态,但如果 Redis 不可用,则回退到内存中的 _memory_store backend/open_webui/utils/rate_limit.py:13

实现细节:

  • 桶分辨率:默认使用 60 秒桶 backend/open_webui/utils/rate_limit.py:33
  • Redis 策略:使用 INCR 操作桶键,并使用 MGET 计算窗口内的总量 backend/open_webui/utils/rate_limit.py:78-92

来源: backend/open_webui/utils/rate_limit.py:6-136