从 mars-sdt 迁移
跑过 C++ 项目网络诊断的 App 有一件事要挪:什么是探测。一次诊断在 C++ 和这里是同样 三步 —— 说出 hosts 和检查项、跑、取报告 —— 报告也是同一个 {"details":[ … ]} 文 档,一项检查一个对象,里面是同样的 detectType、errorCode 和那些耗时,所以今天 已经在读报告的东西,这份也读得懂。
| 你用的那一块 | 这里拿什么 | 写在哪一页 |
|---|---|---|
mars/sdt | JitPack 上的 marsrs 和同名的 crate(crates.io 还没发布),共享 Kotlin 模块的 marsrs-kmp,Apple 上的 MarsRSNet | 快速开始 |
mars/xlog | xlog —— 日志,在自己的一个包里 | 从 mars-xlog 迁移 |
mars/stn | 同一个 marsrs,和诊断在同一个包里 | 从 mars-stn 迁移 |
那几个调用叫什么
| 什么 | C++ | Rust | Android、共享 Kotlin | Swift | C |
|---|---|---|---|---|---|
| hosts 和 mode | StartActiveCheck | start_active_check(…) | startActiveCheck(…) | startActiveCheck(…) | mars_sdt_start_active_check(…) |
| 跑计划 | __RunOn 那个线程 | run_checks(&mut ask, net) | runChecks(net, probe) | runChecks(networkType:probe:) | mars_sdt_run_checks(ctx, probe, net) |
| 停掉 | CancelActiveCheck | cancel_active_check() | cancelActiveCheck() | cancelActiveCheck() | mars_sdt_cancel_active_check() |
| net-check 的 CGI | SetHttpNetcheckCGI(cgi) | set_http_netcheck_cgi(cgi) | setHttpNetcheckCGI(cgi) | setHTTPNetCheckCGI(cgi) | mars_sdt_set_http_netcheck_cgi(cgi) |
| 报告 | Callback::ReportNetCheckResult | report_json(&results) | takeReport(),或那个回调 | takeReport() | mars_sdt_take_report(buf, len) |
mode 是同一套 bit —— 先 ping 和 DNS,再 net-check CGI 的那次 HTTP,再 TCP —— 0 还是一项都不跑,也还是没有哪个接口会跑它:Rust 和 Android 回答 false,C ABI 回答 MARS_SDT_ERR_BAD_ARG。 在 Rust 里这些 bit 有了名字:Mode::NONE、BASIC、LONG、 SHORT 和 ALL,用 | 拼起来,mode.bits() 交回上游那个调用要的 i32。见 检查项。
在 Rust 里那三步也是一个调用: sdt.diagnose(longlink, shortlink, mode, timeout, &mut ask, net) 就是 start_active_check、run_checks 和报告,已经有检查在跑的时候它回答 None —— 也就 是上游那个调用的 false。start_active_check 没有带 deprecated:一个要跨线程驱动 这趟跑的宿主 —— 在一个线程上开检查,在另一个线程上取报告 —— 还是要把这三个调用分开 用。
App 接过去的那两件事
探测是 App 的。 C++ 把自己的 socket 链进那些 checker,所以那边的一次诊断只能对 着平台自己的网络跑。这里一项检查是这一趟问你的一个问题 —— 要解析的一个域名、要连的 一个 ip 和端口、要取的一个 URL、要 ping 的一个 host —— 你回答什么,报告就记下什么。 在 Android 和共享 Kotlin 上,这是你交给 runChecks 的那个 IProbe;在 Rust 里是那 个 Ask;在 Swift 和 C 里是那个闭包。见探测。
本该是一个线程的地方,是一次调用。 C++ 在它的 __RunOn 线程上跑诊断;这个移植 里没有线程,所以 runChecks 在调用它的那个线程上问它的探测,所有探测回答了才返回 —— App 跑一趟、取报告,没有循环,也没有 sleep。把两个调用合成一个的 diagnose 是 一样的,而且它不是一个 future:想让这趟诊断离开当前线程的 App 自己把它挪过去。
取走报告就清空了,mars_sdt_take_report 的 buffer 在报告塞不下时会把结果留着 —— 见报告。
接着看
- 快速开始 —— 每个带着 SDT 的平台上的依赖和一整趟诊断。
- 从 mars-xlog 迁移 —— 日志,给那些除了诊断 还拿了别的东西的应用。
- 从 mars-stn 迁移 —— 任务链路,和诊断在同一个 包里。