跳转到内容

快速开始

本指南带你从零编译 pair-demo 命令行工具,并使用手机介绍器(Android 原生应用或本地启动的 Web 扫码页面)完成两个终端端点的配对、本地 Matrix SAS 核对与受保护业务通信。

仓库根目录提供 devenv 环境定义(固定 Rust、Node.js、Yarn 4.10.3、JDK 17 与 Android SDK/NDK,详见 docs/build-environment.md)。在仓库根目录构建演示 CLI:

终端窗口
cargo build -p pair-demo

编译完成后,可执行文件位于 ./target/debug/pair-demo。可以通过 --help 查看所有子命令:

终端窗口
./target/debug/pair-demo --help

pair-demo 提供两类演示路径:

  • pair-demo chat:配对验证后,在两个端点之间建立受 PairingGate 保护的 iroh-gossip 双向文本聊天室。
  • pair-demo invite:配对验证后,执行可选的验证后 payload 交换(上限 64 KiB)与受保护的 /iroh-pairing/demo-echo/1 业务回显证明。

两个对等端点的介绍必须由独立的介绍者递交(pair-demo 没有内置 introduce 子命令)。你可以选择以下任一方式准备手机介绍器:

方式 A:Android 原生应用(connector-android)

Section titled “方式 A:Android 原生应用(connector-android)”

构建并安装 arm64-v8a debug APK(最低支持 Android 10 / API 29):

终端窗口
cd apps/connector-android
printf 'sdk.dir=%s\n' "$ANDROID_HOME" > local.properties
./gradlew --no-daemon assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

Android 包名变更说明:应用包名(applicationId)为 com.gjz010.irohpairing。如果设备上曾安装过旧包名 computer.iroh.pairing.android 的构建版本,新 APK 不会原地覆盖旧应用;两者可在设备上并存,确认迁移完成后可自行卸载旧应用。

connector-android 启动后即按默认**“自动”**网络模式(iroh 官方 presets::N0:UDP 直连 + N0 生产 relay + DNS 发现)完成初始化,无需额外配置即可直接扫码。

方式 B:静态 Web 应用 / PWA(connector-web)

Section titled “方式 B:静态 Web 应用 / PWA(connector-web)”

connector-web 已随同一 Pages 站点发布于 https://iroh-pairing.gjz010.page/pair/(支持作为 PWA 安装到主屏幕;当通过 CLI --connector-url 生成带入口地址的邀请时,协议规范要求仍传入无尾斜杠的 https://iroh-pairing.gjz010.page/pair)。

在已按 docs/build-environment.md 准备好 Rust / WASM / Node.js 工具链的本地环境中,也可先安装依赖再构建并启动预览服务(参阅部署指南了解 /pair/ 合并发布与独立部署):

终端窗口
cd apps/connector-web
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 node .yarn/releases/yarn-4.10.3.cjs install --immutable
node .yarn/releases/yarn-4.10.3.cjs build
node .yarn/releases/yarn-4.10.3.cjs vite preview --host 127.0.0.1 --port 4173

随后在浏览器打开 http://127.0.0.1:4173。注意:connector-web 运行在浏览器 WASM 环境中(browser_relay 模式),无法建立原生直接 UDP 连接;即使已安装 PWA 并离线打开界面壳,或与两个终端处于同一局域网,实际配对仍必须经过可达的 iroh relay(默认支持官方 N0 relay)。

3. 快速体验一:双端点交互聊天室(pair-demo chat)

Section titled “3. 快速体验一:双端点交互聊天室(pair-demo chat)”

打开两个终端窗口,分别启动端点 A 和端点 B(默认使用 iroh 官方 presets::N0 网络配置):

终端窗口
# 终端 1(端点 A)
./target/debug/pair-demo chat --name A
# 终端 2(端点 B)
./target/debug/pair-demo chat --name B

每个终端都会在 stderr 打印终端二维码以及一行可供复制粘贴的备用邀请文本:

Invitation (paste/scan): <base64url-envelope>

接着按以下步骤完成配对与聊天:

  1. 依次录入两份邀请:在手机介绍器底部点击唯一主按钮**“扫码 / Scan”,先扫描终端 1 的二维码(或在扫码弹层内点击“改用粘贴邀请 / Paste invite instead”粘贴终端 1 的邀请字符串),填充端点 A** 卡片;再次点击底部**“扫码 / Scan”读取终端 2 的邀请,填充端点 B** 卡片。
  2. 自动触发介绍:当第二份有效且兼容的邀请录入后,手机端自动向两个端点发起 Introduce,并在收齐双端回执(handoff)后提示**“请在两个端点上确认”**。
  3. 在两个终端本地确认 SAS:终端 1 和终端 2 各自显示派生的 7 个 Matrix SAS 表情(含英文名、简体中文名)及 3 个十进制数。核对两端显示完全一致后,在两个终端分别输入 yes(或 y / 是 / 一致 / 完全一致)并回车。
  4. 收发聊天消息与退出:双端验证通过并交换公开候选 topic 后,终端打印 Chat joined with verified peer ...。此时在任一终端直接输入文字并回车即可实时收发(单行上限 4096 字节);输入 /quit、按 Ctrl-C 或关闭 stdin 即可干净退出,并在 stdout 输出单行脱敏统计 JSON。

4. 快速体验二:一次性配对、载荷交换与回显证明(pair-demo invite)

Section titled “4. 快速体验二:一次性配对、载荷交换与回显证明(pair-demo invite)”

若需验证带回执的验证后 payload 交换与一次性 PairingGate 业务连接,可在两个终端运行 invite 子命令:

终端窗口
# 终端 1:附带验证后交换的 JSON 文件
printf '{"hello":"from-a"}\n' > /tmp/payload-a.json
./target/debug/pair-demo invite --name A \
--payload-file /tmp/payload-a.json \
--content-type application/json \
--schema-version 1
# 终端 2
./target/debug/pair-demo invite --name B

用手机介绍器依次扫描 A、B 并在两个终端分别输入 yes 后:

  1. 双方在已验证的配对通道上交换各自声明的 payload,接收端显示 content_type、字节数与 SHA-256 摘要并显式发送协议回执(accept_payload_with_digest)。
  2. 双方授予 /iroh-pairing/demo-echo/1 一次性访问权限(GrantLifetime::Once),由 EndpointId 字典序较小的一端发起一次受保护回显请求。
  3. 成功后,pair-demo invite 会保持会话与 Endpoint 存活 3 秒(有界观察窗口),使手机端 Observe 轮询能够读取到双端 ExchangeComplete 状态并显示“两个端点均已报告完成”,随后两个终端以退出码 0 输出结构化结果 JSON。

connector-web 浏览器界面在两个终端各自完成本地确认后显示两个端点均已报告完成
图为 connector-web 浏览器端界面:两个终端各自在本机输入 yes 完成验证与交换后,手机端通过 Observe 观察到双方均已报告完成。

5. 可选:纯局域网离线模式(--lan-only)

Section titled “5. 可选:纯局域网离线模式(--lan-only)”

仅当你的运行环境完全不访问任何公网 relay 或 DNS 发现,且 Android 手机与两台被配对设备处于同一可互通的局域网时,可使用纯局域网模式:

  1. 在 connector-android 页头右上角点击齿轮图标(设置),在高级网络设置中选择**“仅局域网”(NativeLan),关闭弹窗后点击页头右上角刷新图标**开始新一组配对使设置生效。
  2. 在两个终端启动命令中显式加上 --lan-only(此时端点不会等待表示 relay 就绪的 Endpoint::online(),只将本机直连 UDP 地址编码进邀请):
终端窗口
# 终端 1
./target/debug/pair-demo chat --name A --lan-only
# 终端 2
./target/debug/pair-demo chat --name B --lan-only

注意:connector-web 受浏览器安全沙箱限制无法直接发起原始 UDP 连接,因此不支持 --lan-only 生成的直连邀请(扫描时会直接提示 relay_required)。

6. 可选:持久身份、重启服务与权限撤销

Section titled “6. 可选:持久身份、重启服务与权限撤销”

默认情况下,pair-demo 的身份密钥与授权记录仅保存在内存中。传入 --state-dir <DIR> 后,pair-demo invite 会在 <DIR>/state.json(目录权限 0700,文件权限 0600)中保存长期身份与 Persistent 授权记录,从而支持跨进程重启复用与显式撤销:

终端窗口
# 1. 使用持久状态目录完成一次配对
./target/debug/pair-demo invite --state-dir ./state-a --name A
./target/debug/pair-demo invite --state-dir ./state-b --name B
# 2. 查看端点 A 保存的已授权对端列表
./target/debug/pair-demo peers list --state-dir ./state-a
# 3. 重启端点 B,仅提供受保护业务 ALPN 服务(不再开启配对邀请)
./target/debug/pair-demo serve --state-dir ./state-b
# 4. 端点 A 使用持久身份访问端点 B 的受保护服务(若 B 端口变化,可通过 --direct 传入 serve 输出的新地址)
./target/debug/pair-demo ping <B-endpoint-id-hex> --state-dir ./state-a
# 5. 在端点 B 上撤销对端点 A 的授权;重启 serve 后,A 的新连接将被 PairingGate 以 403 拒绝
./target/debug/pair-demo peers revoke <A-endpoint-id-hex> --state-dir ./state-b

本地自动化测试已覆盖上述 CLI 与介绍器流程;在跨公网 NAT 穿透或物理手机真机相机环境下使用时,请结合目标网络环境实际验证。