remote/linux-agent/src/main.rs
yu 9c340813a8 feat(agent): 新增 agent-core 与 Linux 被控端(X11 + XTest,纯新增不动 agent/)
本期只在新增文件里做,**未改动 Windows agent/ 一个字节**(与 NVENC 线并行,避免争抢)。

- 新增 agent-core:平台无关会话层 —— QUIC/TLS 握手、传输调优(沿用 512KB 发送窗口
  结论)、验证码认证、会话/select 循环、latest-wins 单槽、输入分发,以及软件编码
  视频管线(openh264)。同步跟进协议新增的 Pong{lost,sent} 下行丢包统计字段
- 新增 linux-agent:X11 GetImage 采集 + 整帧变更检测;XTest 注入 + 扫描码→X11
  keycode 映射(主键区 = scancode+8,E0 扩展键必须查表,含单元测试)
- 协议零改动:复用 Set-1 扫描码与虚拟桌面归一化坐标,viewer 无需任何修改
- 新增端到端冒烟测试 tests/smoke.rs 与 scripts/linux-smoke.sh(自建 Xvfb,无需
  图形桌面):采集→编码→QUIC 解帧、认证(含错误码拒绝)、Ping/Pong(含丢包字段)、
  静止桌面关键帧恢复、输入注入实证(注入后从另一条 X11 连接读回指针真实坐标)
- 该关键帧用例做过变异测试:把修复退回会失败、恢复后通过,确认断言有效
- .gitattributes:shell 脚本强制 LF(Windows checkout 成 CRLF 会导致容器内无法执行)
- 手册:修正已失效的工具链路径;补充 cargo 镜像;新增第 8 节(Linux)与 6.1 节
  (三条待修问题,含两条 Windows 侧仍存在的关键帧缺陷)

验证:
- Linux(容器, USTC 源 + Xvfb): cargo test -p linux-agent 通过,2 passed
- Windows: 本期未改 agent/,default-members 未变,`cargo build --release` 行为不变
2026-10-23 13:31:08 +08:00

32 lines
1.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! Linux 被控端:X11 采集 + XTest 注入;会话层(QUIC/认证/编码/丢帧)复用 `agent-core`。
//!
//! 与 Windows 端的差异仅在这两个模块里,线格式与主控端完全一致,viewer 不需要任何改动。
//! 依赖 `DISPLAY` 环境变量(Xorg / XWayland 均可)。
mod capture;
mod input;
use agent_core::{parse_args, serve, EncoderSettings, InputInjector, ScreenCapturer, SessionConfig};
use anyhow::Result;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<()> {
let (port, code) = parse_args()?;
let display = std::env::var("DISPLAY").unwrap_or_else(|_| "(未设置)".to_string());
println!("[linux-agent] DISPLAY={display}");
// 注入端连接常驻(启动即校验 XTEST 扩展是否可用,缺了就直接报错退出)
let injector: Arc<dyn InputInjector> = Arc::new(input::X11Injector::new()?);
serve(
SessionConfig { port, code },
EncoderSettings::default(),
// 采集端可被重建(X11 连接断开等),故用工厂闭包
|| Ok(Box::new(capture::X11Capturer::new()?) as Box<dyn ScreenCapturer>),
injector,
)
.await
}