目标与挑战:拥抱“实时”,拒绝“脆弱”
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.rs
与commands.rs
,并在PollSnapshot::collect
中聚合; - 统一错误码与限流策略,使跨域协作稳定;
- 文档化差异:以「领域说明 + 示例」形式沉淀,降低新人上手成本。
收官
适配层 + 统一轮询,让 LCU 驱动的桌面助手既能“紧贴实时”,又保持稳定可控。结合 Rust 的并发安全与 Vue 的响应式生态,Nidalee 在性能、可维护与体验之间达成了平衡。
相关阅读: