乐于分享
好东西不私藏

【Hermes Agent源码系列】 多平台网关:一个进程如何同时服务16+个消息平台

【Hermes Agent源码系列】 多平台网关:一个进程如何同时服务16+个消息平台

前面拆了对话循环和工具系统,今天拆 Hermes Agent 最"重"的一个模块——多平台消息网关。

gateway/run.py 有 856KB,是整个项目最大的单文件。它用一个进程同时对接 Telegram、Discord、Slack、飞书、企业微信、WhatsApp、Signal 等 16+ 个消息平台。用户在任何平台发消息,Agent 都能收到并回复——体验完全一致。

概述

Hermes Agent 的 Gateway 系统是一个多平台消息路由层,支持 20+ 个消息平台(Telegram、Discord、Slack、WhatsApp、Signal、Matrix、Feishu、WeCom 等),将不同平台的消息协议统一转换为标准化的内部事件流,并将 Agent 响应路由回原平台。

核心价值

  • • 统一接口:所有平台适配器实现相同的 BasePlatformAdapter 接口
  • • 会话管理:跨平台的会话持久化与上下文注入
  • • 媒体处理:图片/音频/文档的本地缓存与 SSRF 防护
  • • 安全隔离:平台级锁、PII 脱敏、URL 安全检查

1. 架构设计

1.1 整体架构

┌─────────────────────────────────────────────────────────────┐│                      Gateway Runner                          ││  (gateway/run.py - 启动所有平台适配器)                       │└────────────┬────────────────────────────────────────────────┘             │             ├─► Platform Adapter 1 (Telegram)             ├─► Platform Adapter 2 (Discord)             ├─► Platform Adapter 3 (Slack)             ├─► Platform Adapter 4 (WhatsApp)             └─► ... (20+ 平台)                      │                      ▼         ┌────────────────────────┐         │  BasePlatformAdapter   │  ◄─── 统一接口         │  - connect()           │         │  - send_message()      │         │  - handle_message()    │         └────────────────────────┘                      │                      ▼         ┌────────────────────────┐         │   MessageEvent         │  ◄─── 标准化消息         │   - text               │         │   - media_urls         │         │   - source (SessionSource) │         └────────────────────────┘                      │                      ▼         ┌────────────────────────┐         │  Session Manager       │  ◄─── 会话持久化         │  - build_session_key() │         │  - SessionContext      │         └────────────────────────┘                      │                      ▼         ┌────────────────────────┐         │   run_agent.py         │  ◄─── 对话循环         │   (AIAgent)            │         └────────────────────────┘

1.2 核心组件

组件
文件
职责
Gateway Runnergateway/run.py
启动所有平台适配器,管理生命周期
Base Adaptergateway/platforms/base.py
定义统一接口,提供公共工具
Platform Adaptersgateway/platforms/*.py
各平台的具体实现(26 个文件)
Session Managergateway/session.py
会话上下文、持久化、重置策略
Configgateway/config.py
平台配置、授权、重置策略
Stream Consumergateway/stream_consumer.py
消费 Agent 输出流,实时推送

2. BasePlatformAdapter 接口

2.1 核心抽象方法

class BasePlatformAdapter(ABC):    @abstractmethod    async def connect(self) -> None:        """连接到平台(登录、建立 WebSocket 等)"""    @abstractmethod    async def send_message(        self,         chat_id: str        text: str        **kwargs) -> SendResult:        """发送消息到指定聊天"""    @abstractmethod    async def send_typing(self, chat_id: str) -> None:        """发送"正在输入"指示器"""    @abstractmethod    def truncate_message(self, text: str) -> str:        """根据平台限制截断消息"""

2.2 公共工具方法

媒体缓存(Image/Audio/Document Cache)

# 图片缓存async def cache_image_from_url(url: str, ext: str = ".jpg") -> str:    """下载图片到本地缓存,返回文件路径"""    # 1. SSRF 防护:检查 URL 是否安全    # 2. 重试机制:429/5xx 错误自动重试    # 3. 魔术字节检查:验证是否为真实图片    # 4. 唯一文件名:img_{uuid12}.jpg# 音频缓存async def cache_audio_from_url(url: str, ext: str = ".ogg") -> str:    """下载音频到本地缓存(用于 STT)"""# 文档缓存def cache_document_from_bytes(data: bytes, filename: str) -> str:    """保存文档到本地缓存,防止路径遍历"""

设计亮点

  • • 本地化媒体:平台 URL 通常有时效性(Telegram 1 小时过期),缓存到本地确保 Vision Tool 可访问
  • • SSRF 防护is_safe_url() 检查 + 重定向守卫(_ssrf_redirect_guard
  • • 重试策略:429/5xx 错误指数退避重试,避免 CDN 抖动丢失媒体

代理支持

def resolve_proxy_url(platform_env_var: str | None = None) -> str | None:    """解析代理 URL(支持 SOCKS/HTTP)"""    # 优先级:    # 1. 平台专用环境变量(DISCORD_PROXY)    # 2. 通用环境变量(HTTPS_PROXY)    # 3. macOS 系统代理(scutil --proxy)def proxy_kwargs_for_bot(proxy_url: str | None) -> dict:    """为 discord.py Bot 构建代理参数"""    # SOCKS → {"connector": ProxyConnector(..., rdns=True)}    # HTTP  → {"proxy": url}

设计亮点

  • • rdns=True:强制通过代理进行 DNS 解析,绕过 GFW DNS 污染
  • • macOS 自动检测:读取系统代理配置,无需手动设置

UTF-16 长度计算

def utf16_len(s: str) -> int:    """计算 UTF-16 编码单元数(Telegram 限制 4096)"""    return len(s.encode("utf-16-le")) // 2def _prefix_within_utf16_limit(s: str, limit: int) -> str:    """二分查找最长前缀,不破坏代理对"""

设计亮点

  • • Telegram 的 4096 字符限制是 UTF-16 编码单元,而非 Unicode 码点
  • • Emoji(😀)占 2 个 UTF-16 单元,Python len() 只计 1 个
  • • 二分查找确保不会在代理对中间截断

3. MessageEvent 标准化

3.1 数据结构

@dataclassclass MessageEvent:    # 消息内容    text: str    message_type: MessageType  # TEXT, PHOTO, AUDIO, DOCUMENT, COMMAND    # 来源信息    source: SessionSource  # 平台、聊天 ID、用户 ID    # 媒体附件(本地文件路径)    media_urls: List[str]    media_types: List[str]    # 回复上下文    reply_to_message_id: Optional[str]    reply_to_text: Optional[str]  # 被回复消息的文本    # 自动加载技能(频道绑定)    auto_skill: Optional[str | list[str]]    # 内部标志(绕过授权检查)    internal: bool = False

3.2 消息类型

class MessageType(Enum):    TEXT = "text"    LOCATION = "location"    PHOTO = "photo"    VIDEO = "video"    AUDIO = "audio"    VOICE = "voice"    DOCUMENT = "document"    STICKER = "sticker"    COMMAND = "command"  # /new, /reset

3.3 照片爆发合并

def merge_pending_message_event(    pending_messages: Dict[str, MessageEvent],    session_key: str,    event: MessageEvent,) -> None:    """合并照片爆发(相册)到同一事件"""    existing = pending_messages.get(session_key)    if (        existing        and existing.message_type == MessageType.PHOTO        and event.message_type == MessageType.PHOTO    ):        # 合并媒体 URL        existing.media_urls.extend(event.media_urls)        existing.media_types.extend(event.media_types)        # 合并标题        if event.text:            existing.text = _merge_caption(existing.text, event.text)        return    # 非照片消息替换待处理事件    pending_messages[session_key] = event

设计亮点

  • • 用户发送相册时,平台通常发送多个 PHOTO 事件
  • • 合并到单个事件,Agent 一次性看到所有图片
  • • 非照片消息不合并,保持时序

4. 会话管理

4.1 SessionSource(会话来源)

@dataclassclass SessionSource:    platform: Platform  # TELEGRAM, DISCORD, SLACK, ...    chat_id: str    chat_name: Optional[str]    chat_type: str  # "dm", "group", "channel", "thread"    user_id: Optional[str]    user_name: Optional[str]    thread_id: Optional[str]  # 论坛主题、Discord 线程    chat_topic: Optional[str]  # 频道描述    @property    def description(self) -> str:        """人类可读描述:DM with Alice, group: DevTeam"""

4.2 SessionContext(会话上下文)

@dataclassclass SessionContext:    source: SessionSource    connected_platforms: List[Platform]  # 所有已连接平台    home_channels: Dict[Platform, HomeChannel]  # 定时任务投递目标    session_key: str  # "telegram:12345"    session_id: str   # UUID    created_at: datetime    updated_at: datetime

4.3 会话密钥构建

def build_session_key(source: SessionSource) -> str:    """构建唯一会话密钥"""    # 基础格式:platform:chat_id    key = f"{source.platform.value}:{source.chat_id}"    # 论坛主题/线程:追加 thread_id    if source.thread_id:        key += f":{source.thread_id}"    return key

设计亮点

  • • 同一聊天的不同线程是独立会话
  • • Telegram 论坛主题、Discord 线程各自独立上下文

4.4 PII 脱敏

def _hash_sender_id(value: str) -> str:    """哈希用户 ID → user_<12hex>"""    return f"user_{hashlib.sha256(value.encode()).hexdigest()[:12]}"def _hash_chat_id(value: str) -> str:    """哈希聊天 ID,保留平台前缀"""    # telegram:12345 → telegram:<hash>

适用平台

  • • WhatsApp、Signal、Telegram、BlueBubbles(电话号码敏感)
  • • Discord 不脱敏:提及系统需要真实 ID(<@123456>

5. 平台适配器实现

5.1 已支持平台(26 个)

平台
文件
特性
Telegramtelegram.py
121KB,最完整实现,支持论坛主题、语音模式、贴纸
Discorddiscord.py
129KB,支持线程、语音频道、Webhook
Slackslack.py
68KB,支持 Socket Mode、线程回复
WhatsAppwhatsapp.py
41KB,通过 WhatsApp Business API
Signalsignal.py
32KB,通过 signal-cli
Matrixmatrix.py
83KB,支持端到端加密
Feishufeishu.py
165KB,飞书企业集成
WeComwecom.py
58KB,企业微信
Weixinweixin.py
67KB,微信公众号
Mattermostmattermost.py
27KB
BlueBubblesbluebubbles.py
34KB,iMessage 桥接
Emailemail.py
23KB,IMAP/SMTP
SMSsms.py
14KB,Twilio
API Serverapi_server.py
80KB,HTTP API
Webhookwebhook.py
26KB,通用 Webhook
HomeAssistanthomeassistant.py
16KB,智能家居
DingTalkdingtalk.py
13KB,钉钉

5.2 Telegram 适配器关键实现

连接与认证

async def connect(self) -> None:    # 1. 获取代理配置    proxy_url = resolve_proxy_url("TELEGRAM_PROXY")    # 2. 创建 Bot 实例    self.bot = Bot(        token=self.config.token,        **proxy_kwargs_for_bot(proxy_url)    )    # 3. 设置命令菜单    await self.bot.set_my_commands([        BotCommand("new", "Start new conversation"),        BotCommand("reset", "Reset conversation"),        # ...    ])    # 4. 启动轮询    await self.application.run_polling()

消息处理

async def _handle_telegram_message(    self,     update: Update,     context: ContextTypes.DEFAULT_TYPE) -> None:    message = update.message or update.edited_message    # 1. 提取来源信息    source = SessionSource(        platform=Platform.TELEGRAM,        chat_id=str(message.chat_id),        chat_name=message.chat.title,        chat_type=self._map_chat_type(message.chat.type),        user_id=str(message.from_user.id),        user_name=message.from_user.username,        thread_id=str(message.message_thread_id) if message.is_topic_message else None,    )    # 2. 处理媒体附件    media_urls = []    if message.photo:        # 下载最高分辨率照片        file = await message.photo[-1].get_file()        url = file.file_path        local_path = await cache_image_from_url(url, ext=".jpg")        media_urls.append(local_path)    # 3. 构建 MessageEvent    event = MessageEvent(        text=message.text or message.caption or "",        message_type=self._detect_message_type(message),        source=source,        media_urls=media_urls,        raw_message=message,        message_id=str(message.message_id),    )    # 4. 调用通用处理器    await self.handle_message(event)

发送消息

async def send_message(    self,     chat_id: str    text: str    **kwargs) -> SendResult:    try:        # 1. 截断消息(Telegram 限制 4096 UTF-16 单元)        text = self.truncate_message(text)        # 2. 提取线程 ID        thread_id = kwargs.get("thread_id")        # 3. 发送消息        sent = await self.bot.send_message(            chat_id=int(chat_id),            text=text,            message_thread_id=int(thread_id) if thread_id else None,            parse_mode="Markdown",        )        return SendResult(            success=True,            message_id=str(sent.message_id),            raw_response=sent,        )    except Exception as e:        return SendResult(            success=False,            error=str(e),            retryable=self._is_retryable_error(e),        )

5.3 Discord 适配器关键实现

线程支持

async def _handle_discord_message(self, message: discord.Message) -> None:    # 检测是否在线程中    thread_id = None    if isinstance(message.channel, discord.Thread):        thread_id = str(message.channel.id)    source = SessionSource(        platform=Platform.DISCORD,        chat_id=str(message.channel.id),        chat_name=message.channel.name,        chat_type="thread" if thread_id else "channel",        user_id=str(message.author.id),        user_name=message.author.name,        thread_id=thread_id,    )

提及处理

def _process_mentions(self, text: str, message: discord.Message) -> str:    """将 <@123456> 转换为 @username"""    for user in message.mentions:        text = text.replace(f"<@{user.id}>", f"@{user.name}")    for role in message.role_mentions:        text = text.replace(f"<@&{role.id}>", f"@{role.name}")    return text

6. 流式输出消费

6.1 StreamConsumer

class StreamConsumer:    """消费 Agent 输出流,实时推送到平台"""    async def consume_stream(        self,        stream: AsyncIterator[str],        adapter: BasePlatformAdapter,        chat_id: str,        **kwargs) -> None:        buffer = ""        last_send_time = time.time()        async for chunk in stream:            buffer += chunk            # 每 2 秒或遇到句子结束符时推送            if (                time.time() - last_send_time > 2.0                or chunk.endswith((".", "!", "?", "\n"))            ):                await adapter.send_message(chat_id, buffer, **kwargs)                buffer = ""                last_send_time = time.time()        # 推送剩余内容        if buffer:            await adapter.send_message(chat_id, buffer, **kwargs)

设计亮点

  • • 实时推送:用户看到 Agent 逐步生成响应
  • • 批量优化:避免每个 token 都发送一次消息
  • • 句子边界:在自然断点处推送,提升可读性

7. 安全机制

7.1 SSRF 防护

async def _ssrf_redirect_guard(response):    """重定向守卫:防止 302 跳转到内网"""    if response.is_redirect and response.next_request:        redirect_url = str(response.next_request.url)        if not is_safe_url(redirect_url):            raise ValueError(f"Blocked redirect to private address: {redirect_url}")

攻击场景

  • • 攻击者发送 https://evil.com/image.jpg
  • • 服务器 302 重定向到 http://169.254.169.254/latest/meta-data/
  • • 未防护的客户端会访问 AWS 元数据服务

7.2 平台锁

def _acquire_platform_lock(self, scope: str, identity: str) -> bool:    """获取平台级锁,防止多实例冲突"""    acquired, existing = acquire_scoped_lock(        scope, identity, metadata={&#x27;platform&#x27;: self.platform.value}    )    if not acquired:        owner_pid = existing.get(&#x27;pid&#x27;)        self._set_fatal_error(            f&#x27;{scope}_lock&#x27;,            f&#x27;Resource already in use (PID {owner_pid})&#x27;,            retryable=False        )        return False    return True

用途

  • • 防止同一 Telegram Bot Token 被多个进程使用
  • • 防止 Discord Bot 重复连接

7.3 路径遍历防护

def cache_document_from_bytes(data: bytes, filename: str) -> str:    # 1. 清理文件名    safe_name = Path(filename).name  # 去除目录部分    safe_name = safe_name.replace("\x00", "").strip()    # 2. 生成唯一文件名    cached_name = f"doc_{uuid.uuid4().hex[:12]}_{safe_name}"    filepath = cache_dir / cached_name    # 3. 验证路径在缓存目录内    if not filepath.resolve().is_relative_to(cache_dir.resolve()):        raise ValueError(f"Path traversal rejected: {filename!r}")    filepath.write_bytes(data)    return str(filepath)

8. 与 LifeOS 的对比

维度
Hermes Agent Gateway
LifeOS MCP Server
定位
多平台消息路由层
本地知识管理服务
协议
各平台原生协议(Telegram Bot API、Discord Gateway)
MCP stdio
会话管理
跨平台持久化(文件系统)
单 Vault 内存 + SQLite
媒体处理
下载到本地缓存
直接读取 Vault 文件
安全机制
SSRF 防护、平台锁、PII 脱敏
路径沙箱、FTS5 注入防护
流式输出
实时推送到平台
工具调用同步返回

可借鉴点

  1. 1. 媒体缓存策略:LifeOS 可为 /read-pdf 添加 URL 下载 + SSRF 防护
  2. 2. 会话上下文注入:LifeOS 可在 system prompt 中注入当前 Vault 路径、活跃项目
  3. 3. 流式输出:LifeOS 可为 /research 等长时任务添加进度推送
  4. 4. 平台锁机制:LifeOS 可防止同一 Vault 被多个 MCP 实例同时访问

9. 关键设计模式

9.1 适配器模式(Adapter Pattern)

# 统一接口class BasePlatformAdapter(ABC):    @abstractmethod    async def send_message(...) -> SendResult: ...# 各平台实现class TelegramAdapter(BasePlatformAdapter): ...class DiscordAdapter(BasePlatformAdapter): ...

优势

  • • 新增平台只需实现 BasePlatformAdapter
  • • Gateway Runner 无需关心平台细节

9.2 事件驱动(Event-Driven)

# 平台适配器 → MessageEvent → 通用处理器event = MessageEvent(text="Hello", source=source)await self.handle_message(event)

优势

  • • 解耦平台协议与业务逻辑
  • • 便于添加中间件(日志、授权、限流)

9.3 策略模式(Strategy Pattern)

class SessionResetPolicy(Enum):    NEVER = "never"    DAILY = "daily"    WEEKLY = "weekly"    ON_COMMAND = "on_command"

优势

  • • 不同聊天可配置不同重置策略
  • • 易于扩展新策略

10. 性能优化

10.1 媒体缓存清理

def cleanup_image_cache(max_age_hours: int = 24) -> int:    """删除超过 24 小时的缓存图片"""    cache_dir = get_image_cache_dir()    cutoff = time.time() - (max_age_hours * 3600)    removed = 0    for f in cache_dir.iterdir():        if f.is_file() and f.stat().st_mtime < cutoff:            f.unlink()            removed += 1    return removed

10.2 重试策略

_RETRYABLE_ERROR_PATTERNS = (    "connecterror",    "connectionreset",    "connecttimeout",    "network",    "broken pipe",)# 指数退避for attempt in range(retries + 1):    try:        return await client.get(url)    except Exception as e:        if attempt < retries:            wait = 1.5 * (attempt + 1)            await asyncio.sleep(wait)

10.3 并发处理

# 每个会话独立处理,不阻塞其他会话self._background_tasks.add(    asyncio.create_task(self._process_message(event)))

11. 错误处理

11.1 致命错误标记

def _set_fatal_error(self, code: str, message: str, *, retryable: bool) -> None:    self._running = False    self._fatal_error_code = code    self._fatal_error_message = message    self._fatal_error_retryable = retryable    # 写入状态文件    write_runtime_status(        platform=self.platform.value,        platform_state="fatal",        error_code=code,        error_message=message,    )

11.2 可重试错误判断

def _is_retryable_error(self, exc: Exception) -> bool:    error_str = str(exc).lower()    return any(        pattern in error_str        for pattern in _RETRYABLE_ERROR_PATTERNS    )

12. 总结

12.1 核心优势

  1. 1. 统一抽象BasePlatformAdapter 隐藏平台差异
  2. 2. 安全优先:SSRF 防护、平台锁、PII 脱敏
  3. 3. 媒体本地化:解决平台 URL 时效性问题
  4. 4. 会话持久化:跨平台统一会话管理
  5. 5. 流式输出:实时推送提升用户体验

12.2 可改进点

  1. 1. 消息队列:当前是内存队列,重启丢失待处理消息
  2. 2. 负载均衡:单进程处理所有平台,可拆分为多进程
  3. 3. 监控告警:缺少 Prometheus 指标导出
  4. 4. 测试覆盖:平台适配器测试依赖真实 Token

12.3 对 LifeOS 的启示

  1. 1. 添加 HTTP 工具:支持 URL 下载 + SSRF 防护
  2. 2. 会话上下文注入:在 system prompt 中注入 Vault 元信息
  3. 3. 流式进度推送:长时任务(/research)可推送中间结果
  4. 4. 多 Vault 隔离:防止同一 Vault 被多个 MCP 实例访问

下一步:Phase 4 - 高级特性分析(Memory System、Plugin Architecture、MCP Integration)

📌 欢迎关注「老王的AI局」每周分享 AI Agent 架构解析、工具实战和行业洞察。

同时承接 Agent项目开发,小程序,web站,后台管理saas系统等 欢迎私聊

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-24 21:02:10 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/790476.html
  2. 运行时间 : 0.120289s [ 吞吐率:8.31req/s ] 内存消耗:4,749.31kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=0dab3e4bc17b2625897dc9ea927e18e8
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000582s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000822s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000380s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000266s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000516s ]
  6. SELECT * FROM `set` [ RunTime:0.000207s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000527s ]
  8. SELECT * FROM `article` WHERE `id` = 790476 LIMIT 1 [ RunTime:0.002858s ]
  9. UPDATE `article` SET `lasttime` = 1782306130 WHERE `id` = 790476 [ RunTime:0.006301s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000269s ]
  11. SELECT * FROM `article` WHERE `id` < 790476 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000659s ]
  12. SELECT * FROM `article` WHERE `id` > 790476 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000385s ]
  13. SELECT * FROM `article` WHERE `id` < 790476 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000731s ]
  14. SELECT * FROM `article` WHERE `id` < 790476 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001204s ]
  15. SELECT * FROM `article` WHERE `id` < 790476 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000900s ]
0.124273s