Nidalee:LCU API 适配与统一轮询实战(可观测 × 幂等 × 高性能)

约 4 分钟阅读

目标与挑战:拥抱“实时”,拒绝“脆弱”

LCU API 是 LoL 客户端本地提供的接口,具备“轻、快、近”的优势,但也存在连接波动、状态切换频繁、接口分散等挑战。Nidalee 的策略是:

  • 统一请求入口与错误映射,隔离 API 细节;
  • 设计「统一轮询」管道,将多源查询合并调度,控制频率与幂等;
  • 提供可观测与可扩展的事件流,以便 UI 即时响应。

适配层设计:薄而稳的边界

典型的请求适配:

rust
// src-tauri/src/lcu/request.rs(示意)
pub struct LcuClient { /* ... */ }

impl LcuClient {
    pub async fn get<T: DeserializeOwned>(&self, path: &str) -> Result<T, AppError> {
        let url = format!("{}{}", self.base, path);
        let res = self.http.get(&url).basic_auth(&self.user, Some(&self.pass)).send().await?;
        map_status(res).await
    }
}

async fn map_status<T: DeserializeOwned>(res: reqwest::Response) -> Result<T, AppError> {
    if res.status().is_success() {
        Ok(res.json::<T>().await?)
    } else {
        let code = res.status().as_u16();
        Err(AppError::Lcu(code))
    }
}

要点:

  • 统一鉴权(LCU 本地 Basic Auth);
  • 统一错误映射为内部错误码,避免上层“魔法字符串”。

统一轮询:一个协调器,多个数据源

核心思路:由一个轮询协调器调度多组查询(游戏相位、选人会话、召唤师/战绩、匹配状态等)。每个查询有自己的周期与“变更检测”,只有状态变化才广播事件。

rust
// src-tauri/src/lcu/unified_polling.rs(示意)
pub async fn run(client: LcuClient, tx: broadcast::Sender<AppEvent>) {
    let mut ticker = tokio::time::interval(Duration::from_millis(800));
    let mut last = PollSnapshot::default();
    loop {
        ticker.tick().await;
        let cur = PollSnapshot::collect(&client).await;
        let diff = cur.diff(&last);
        for ev in diff.events { let _ = tx.send(ev); }
        last = cur;
    }
}

“只在变化时更新”的好处:

  • 减少 UI 无效刷新;
  • 为活动日志与侧边通知提供统一入口;
  • 方便后续追加新领域(如活动面板/统计)的监听。

幂等与频控:快,但不打扰

  • 周期性:不同域可设置不同采样周期(如 gameflow 高频、ranked 低频);
  • 幂等:快照差异对比;重复事件被抑制;
  • 退避:当 LCU 连接不可用时退避或暂停轮询,提高性能。

UI 订阅与缓存:事件做信号,缓存做底座

前端使用 @tanstack/vue-query 作为数据缓存主干,事件流作为“增量更新”信号:

ts
// useGamePhaseManager.ts(示意)
const { data: phase } = useQuery({ queryKey: ['gameflow_phase'], queryFn: fetchPhase })

subscribe('GameflowChanged', () => invalidateQueries(['gameflow_phase']))

可观测性:让行为有迹可循

  • 统一 useActivityLogger 记录关键事件(开始匹配、进入选人、锁定英雄、进入结算等);
  • 事件 → 面板/气泡/系统通知(可配置)。

扩展与维护:边界稳定,演进从容

  • 新域的接入:增加一个 service.rscommands.rs,并在 PollSnapshot::collect 中聚合;
  • 统一错误码与限流策略,使跨域协作稳定;
  • 文档化差异:以「领域说明 + 示例」形式沉淀,降低新人上手成本。

收官

适配层 + 统一轮询,让 LCU 驱动的桌面助手既能“紧贴实时”,又保持稳定可控。结合 Rust 的并发安全与 Vue 的响应式生态,Nidalee 在性能、可维护与体验之间达成了平衡。

相关阅读:

相关文章