Files
DevFlow/crates/df-tunnel/examples/e2e_u_relay.rs
T
lxy d9e0ce73d1 优化: 跨端链路协议对齐
- miniapp 配置域旧端点强制重置
- df-tunnel 隧道协议与 relay 现网对齐
- relay e2e 例程入 examples
2026-10-04 16:27:31 +08:00

69 lines
2.6 KiB
Rust

//! df-tunnel ↔ u-relay 端到端联调(Agent 侧握手 + 存活 + 断开)
//!
//! 起 WsTunnelClient 连本机 u-relay :19180 /ws/agent:
//! 1. Hello{kind:"agent", channel_id, token} → u-relay 立即回 hello_ack(3s PROBE 内收到)
//! 2. send_raw_event 发一条事件(relay 无 commander 在线 → 静默丢弃,不报错)
//! 3. 存活 2s(收发循环稳定,无 panic)
//! 4. 优雅 disconnect
//!
//! 运行:先起 u-relay(U_RELAY_TOKEN=devflow-relay-default-token U_RELAY_ADDR=127.0.0.1:19180),
//! 再 `cargo run -p df-tunnel --example e2e_u_relay`。
use std::sync::Arc;
use std::time::Duration;
use df_tunnel::tunnel::CommandHandler;
use df_tunnel::{TunnelClient, WsTunnelClient};
use tokio::sync::Mutex;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let url = "ws://127.0.0.1:19180/ws/agent";
let channel_id = "test-channel-e2e-01";
let token = "devflow-relay-default-token";
let client = Arc::new(WsTunnelClient::new());
// 注册 command 回调(收 commander 指令;本测试预计不触发)
let got_cmd = Arc::new(Mutex::new(0usize));
let counter = got_cmd.clone();
let on_command: CommandHandler = Arc::new(move |_payload| {
let counter = counter.clone();
Box::pin(async move {
*counter.lock().await += 1;
})
});
println!("[1] connect {url} channel={channel_id}");
client
.connect(url, channel_id, token, on_command)
.await
.map_err(|e| anyhow::anyhow!("connect 失败: {e}"))?;
println!(" connect Ok");
assert!(client.is_connected(), "is_connected 应为 true");
println!("[2] is_connected == true ✓(u-relay 已回 hello_ack,握手成功)");
// 发一条原始事件(relay 无 commander 在线 → 静默丢弃,不应报错)
client
.send_raw_event(serde_json::json!({"type": "e2e_probe", "note": "df-tunnel e2e"}))
.await
.map_err(|e| anyhow::anyhow!("send_raw_event 失败: {e}"))?;
println!("[3] send_raw_event Ok(事件出站;relay 无对端静默丢弃符合预期)");
// 保持 2s 让心跳/收发循环稳定跑(无 panic 即可)
tokio::time::sleep(Duration::from_secs(2)).await;
assert!(client.is_connected(), "2s 后仍应 connected(心跳保活)");
println!("[4] 2s 存活 ✓");
// 优雅断开
client.disconnect().await?;
assert!(!client.is_connected(), "disconnect 后 is_connected 应为 false");
println!("[5] disconnect Ok,is_connected == false ✓");
let got = *got_cmd.lock().await;
println!("───");
println!("df-tunnel ↔ u-relay E2E: 5/5 通过(command 收到 {got} 条,预期 0)");
Ok(())
}