Skip to content

OpenDWeb v0.4.2:改进设备组网,简化服务接入

jixoai v0.4.2 opendweb

opendweb 仓库的第一份 GitHub Release,六个 npm 包一并发布。OpenDWeb 做应用级组网:设备凭邀请加入,网络只承载这一个应用的流量;服务端一条命令,客户端只配一个入口,QUIC 直连优先、自托管 relay 回退。

$ curl http://localhost:8787/healthz
200

OpenDWeb 0.4.2 发布了(2026-09-06,jixoai/opendweb 仓库的第一份 GitHub Release)。同一个应用的多台设备组成一个逻辑网络:设备凭邀请加入,网络只承载这一个应用的流量,不必为一条连接给整台机器装系统级 VPN、把全部设备的全部流量都交出去。六个 npm 包都已发布。本篇按主题分节介绍。

服务端一条命令,客户端只配一个入口

两台机器上的同一个应用要互通,服务端起一次,客户端配一次。

# 1. 起服务端(gateway + relay)
npx opendweb server
#   或:docker run -p 8787:8787 -p 3340:3340 ghcr.io/jixoai/opendweb:0.4.2

# 2. 每台客户端一次性配置(持久化到 ~/.opendweb/config.json)
npx @jixo/opendweb-example config set relay http://192.168.2.13:8787

客户端只需要知道 gateway 的地址(8787)。relay 的地址经 gateway 的 /services.json 自动发现,客户端不必知道 3340 端口的存在。

服务端启动后,两条 curl 可以验证:curl http://localhost:8787/healthz 返回 200,curl http://localhost:8787/services.json 返回服务清单。端到端回归有一份手册 EXAMPLE.md(中文版),每次发布后照走一遍。

示例:两端各开一个终端,兑换邀请并聊天
# 3. 终端 A:初始化并保持 chat 会话(签发邀请)
npx @jixo/opendweb-example init --data ~/.dweb-a
npx @jixo/opendweb-example invite --data ~/.dweb-a --ttl 30m   # 复制令牌
npx @jixo/opendweb-example chat --data ~/.dweb-a

# 4. 终端 B(另一目录/设备):兑换邀请并聊天
npx @jixo/opendweb-example join --data ~/.dweb-b <token>
npx @jixo/opendweb-example chat --data ~/.dweb-b

设备凭邀请加入,失败有稳定错误码

新设备不能自行加入网络,要拿到一张邀请令牌去兑换。受控邀请有两个硬条件:令牌只能兑一次;兑换期间签发者的进程保持运行(例如终端 A 开着 chat 会话)。

加入失败返回稳定错误码,格式为 error[join/<code>]。完整六个码覆盖无路径、离线、目录不匹配、过期、重复兑换与损坏,故障对照表见 EXAMPLE.md。NO_REACHABLE_PATH 秒败并给出指引;DIAL_TIMEOUT 在 30 秒内落定,提示签发者大概率已离线。

机制:四层结构与各自的信任来源
  • 身份层:每台设备一个 Ed25519 密钥对,即 EndpointId。它与网络地址解耦,机器换 IP 身份不变,展示串为 z-base-32。

  • 名册层:谁在网络里由一组签名事实决定(Genesis/Grant/Join/Revoke),BLAKE3 内容寻址,多份副本按 union-merge 收敛。邀请兑换走 challenge-response 证明持有密钥,invite_id 按 CAS 消费,保证只兑一次。

  • 会话层:iroh 1.1 提供 QUIC 直连、NAT 穿透与自托管 relay 回退;双 ALPN 分开常规流量与 redeem 兑换;两侧先门控后传数据;帧资源有上限。

  • 同步层:不透明 envelope 双向收发,上层协议自己解释。Automerge 适配器另行交付。

六个 npm 包,各管一件事

npm 包版本角色
opendweb0.4.2服务端 CLI:npx opendweb server 起自托管 gateway(8787)+ relay(3340);插件市场宿主
@jixo/opendweb-server-binary0.3.2CLI 使用的服务端二进制包装;另暴露可编程 startServer()
@jixo/opendweb-client-sdk0.3.2在你自己的应用里嵌入 opendweb 组网内核的 Node SDK(napi-rs;darwin-arm64 / win32-x64)
@jixo/opendweb-example0.3.2双进程参考客户端 CLI(init / invite / join / chat)
@jixo/opendweb-config0.1.0本地插件文件的 definePlugin helper(运行时无关:deno / bun / node)
@jixo/opendweb-ext-cf1.0.3Cloudflare Tunnel 插件:API 推送 ingress、DNS 路由与端到端校验,可选托管 cloudflared

Windows 产物(dweb-server exe 与 napi dll)由 tag workflow 用 mingw 交叉编译现场构建,直接装进 npm tarballs,不需要单独下载。

其余变更

  • 插件安装显式锁版本:opendweb plugin add cf 安装插件,并把 name@version 锁进 ~/.opendweb/plugins.json。祖先目录里一份带过期依赖范围的 package.json 不再能劫持版本解析。

  • ext-cf v1.0 重写:没有公网 IP 的服务端接到 Cloudflare Tunnel 后面。认证只要一个凭据,浏览器登录一次或贴一个 API token;v0.x 需要管理 token 与连接 token 两个。cf setup 幂等,重跑向目标状态收敛;cloudflared 可交给插件托管;token 粘贴支持整块或单条。插件自身运行时零依赖。

    opendweb cf plan --hostname dweb.example.com    # 零副作用预览(setup 亦有 --dry-run)
    opendweb cf setup --hostname dweb.example.com   # 非交互:API 推 ingress、路由 DNS、端到端自检
    

    重写经过一轮 Codex 复核整改,落点包括 SDK 叶子导入、config-merge PUT、OAuth 持久化契约、安装路径与竞态修复。控制面默认走自研 REST 客户端直连 Cloudflare API,CF_CLIENT=sdk 可切换官方 SDK 对照。Ingress 始终整条替换并以 http_status:404 兜底;隧道配置归 opendweb 所有,不要手工挪作他用。

  • 发布自动化:从下一个 tag 起,release workflow 的自动 release notes 接管变更记录的生成。

这是本仓库的第一篇发布记录,提交统计覆盖全部历史:截至 0.4.2 共 98 个提交,27 feat / 44 fix / 9 docs / 3 test / 5 chore / 2 refactor,其余 8 个为 release、style 与 openspec 登记(口径为 conventional 提交前缀计数)。破坏性口径:5 个提交带 ! 标记,4 个是 dweb-fabric 内核早期重构,1 个是 0.4.0 的 cf 凭据拆分,已被 v1.0 的单凭据流程取代;从 v0.x 升级 ext-cf 的读者重新认证一次即可。

升级

npx opendweb@0.4.2 server          # 或:npm i -g opendweb@0.4.2
npm i @jixo/opendweb-client-sdk@0.3.2
docker run -d -p 8787:8787 -p 3340:3340 ghcr.io/jixoai/opendweb:0.4.2

镜像统一在 ghcr.io/jixoai/opendweb:0.4.2 镜像当年发布在改名前的历史命名空间 ghcr.io/gaubee/dweb,改名后全部历史 tag 已原样迁移过来(digest 不变),旧地址暂可拉取,请迁移到新地址。

致谢

会话层站在 iroh 1.1 之上:QUIC 直连、NAT 穿透与自托管 relay 回退都由它提供;SDK 的绑定来自 napi-rs。

链接