mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 06:47:30 +08:00
6.8 KiB
6.8 KiB
Node P2P E2E
这份文档用于验证 gateway.nodes.p2p 的两条真实数据面:
websocket_tunnelwebrtc
目标不是单元测试,而是两台公网机器上的真实联通性验证。
验证目标
验证通过需要同时满足:
- 两台远端 node 都能成功注册到同一个 gateway
websocket_tunnel模式下,远端 node 任务可成功完成webrtc模式下,远端 node 任务可成功完成webrtc模式下,/webui/api/nodes的p2p.active_sessions大于0Dashboard/Subagents能看到 node P2P 会话状态和最近调度路径
前置条件
- 一台 gateway 机器
- 两台远端 node 机器
- 三台机器都能运行
clawgo - 远端机器有
python3 - gateway 机器对外开放 WebUI / node registry 端口
推荐:
- 先验证
websocket_tunnel - 再切到
webrtc webrtc至少配置一个可用的stun_servers
测试思路
为了排除 HTTP relay 误判,建议让目标 node 的 endpoint 故意写成只对目标 node 本机有效的地址,例如:
http://127.0.0.1:<port>
这样如果任务仍能完成,就说明请求不是靠 gateway 直接 HTTP relay 打过去的,而是走了 node P2P 通道。
建议配置
1. websocket_tunnel
{
"gateway": {
"host": "0.0.0.0",
"port": 18790,
"token": "YOUR_GATEWAY_TOKEN",
"nodes": {
"p2p": {
"enabled": true,
"transport": "websocket_tunnel",
"stun_servers": [],
"ice_servers": []
}
}
}
}
2. webrtc
{
"gateway": {
"host": "0.0.0.0",
"port": 18790,
"token": "YOUR_GATEWAY_TOKEN",
"nodes": {
"p2p": {
"enabled": true,
"transport": "webrtc",
"stun_servers": ["stun:stun.l.google.com:19302"],
"ice_servers": []
}
}
}
}
最小 node endpoint
在每台远端 node 上启动一个最小 HTTP 服务,用于返回固定结果:
#!/usr/bin/env python3
import json
import os
import socket
from http.server import BaseHTTPRequestHandler, HTTPServer
PORT = int(os.environ.get("PORT", "19081"))
LABEL = os.environ.get("NODE_LABEL", socket.gethostname())
class H(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
pass
def do_POST(self):
length = int(self.headers.get("Content-Length", "0") or 0)
raw = self.rfile.read(length) if length else b"{}"
try:
req = json.loads(raw.decode("utf-8") or "{}")
except Exception:
req = {}
action = req.get("action") or self.path.strip("/")
payload = {
"handler": LABEL,
"hostname": socket.gethostname(),
"path": self.path,
"echo": req,
}
if action == "agent_task":
payload["result"] = f"agent_task from {LABEL}"
else:
payload["result"] = f"{action} from {LABEL}"
body = json.dumps({
"ok": True,
"code": "ok",
"node": LABEL,
"action": action,
"payload": payload,
}).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
HTTPServer(("0.0.0.0", PORT), H).serve_forever()
注册远端 node
在每台 node 上执行:
clawgo node register \
--gateway http://<gateway-host>:18790 \
--token YOUR_GATEWAY_TOKEN \
--id <node-id> \
--name <node-name> \
--endpoint http://127.0.0.1:<endpoint-port> \
--actions run,agent_task \
--models gpt-4o-mini \
--capabilities run,invoke,model \
--watch \
--heartbeat-sec 10
验证注册成功:
curl -s -H 'Authorization: Bearer YOUR_GATEWAY_TOKEN' \
http://<gateway-host>:18790/webui/api/nodes
预期:
- 远端 node 出现在
nodes online = true- 主拓扑中出现
node.<id>.main
建议的任务验证方式
不要通过普通聊天 prompt 让模型“自己决定是否调用 nodes 工具”作为主判据。
更稳定的方式是直接调用 subagent runtime,把任务派给远端 node branch:
curl -s \
-H 'Authorization: Bearer YOUR_GATEWAY_TOKEN' \
-H 'Content-Type: application/json' \
http://<gateway-host>:18790/webui/api/subagents_runtime \
-d '{
"action": "dispatch_and_wait",
"agent_id": "node.<node-id>.main",
"task": "Return exactly the string NODE_P2P_OK",
"wait_timeout_sec": 30
}'
预期:
ok = trueresult.reply.status = completedresult.reply.result含远端 endpoint 返回内容
websocket_tunnel 判定
在 websocket_tunnel 模式下,上面的任务应能成功完成。
如果目标 node 的 endpoint 配成了 127.0.0.1:<port>,且任务仍成功,则说明:
- 不是 gateway 直接 HTTP relay 到远端公网地址
- 实际请求已经通过 node websocket 隧道送达目标 node
webrtc 判定
切到 webrtc 配置后,重复同样的 dispatch_and_wait。
随后查看:
curl -s -H 'Authorization: Bearer YOUR_GATEWAY_TOKEN' \
http://<gateway-host>:18790/webui/api/nodes
预期 p2p 段包含:
transport = "webrtc"active_sessions > 0nodes[].status = "open"nodes[].last_ready_at非空
这表示 WebRTC DataChannel 已经真正建立,而不只是 signaling 被触发。
WebUI 判定
验证页面:
Dashboard- 能看到 Node P2P 会话明细
- 能看到最近节点调度记录,包括
used_transport和fallback_from
Subagents- 远端 node branch 的卡片/tooltip 能显示:
- P2P transport
- session status
- retry count
- last ready
- last error
- 远端 node branch 的卡片/tooltip 能显示:
常见问题
1. gateway 端口上已经有旧实例
现象:
- 新配置明明改了,但
/webui/api/version或/webui/api/nodes仍表现出旧行为
处理:
- 先确认端口上实际监听的是哪一个
clawgo进程 - 再启动测试实例
2. chat 路由干扰 node 工具验证
现象:
- 普通聊天请求被 router 或 skill 行为分流
- 没有真正命中
nodes数据面
处理:
- 直接用
/webui/api/subagents_runtime的dispatch_and_wait - 让任务明确走
node.<id>.main
3. webrtc 一直停在 connecting
优先检查:
stun_servers是否可达- 两端机器是否允许 UDP 出站
- 是否需要
turn:/turns:服务器
4. 任务成功但 UI 没显示会话
优先检查:
- 是否真的运行在
webrtc配置下 /webui/api/nodes返回的p2p是否含active_sessions- 前端是否已经更新到包含 node P2P runtime 展示的版本
回归建议
每次改动以下模块后,至少回归一次本流程:
pkg/nodes/webrtc.gopkg/nodes/transport.gopkg/agent/loop.gopkg/api/server.gocmd/clawgo/cmd_node.gocmd/clawgo/cmd_gateway.go