mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-04 14:17:30 +08:00
feat: add turn-ready node p2p config
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"clawgo/pkg/providers"
|
||||
"clawgo/pkg/runtimecfg"
|
||||
"clawgo/pkg/sentinel"
|
||||
"github.com/pion/webrtc/v4"
|
||||
)
|
||||
|
||||
func gatewayCmd() {
|
||||
@@ -133,16 +134,37 @@ func gatewayCmd() {
|
||||
if loop == nil || server == nil || runtimeCfg == nil {
|
||||
return
|
||||
}
|
||||
buildICEServers := func() []webrtc.ICEServer {
|
||||
out := make([]webrtc.ICEServer, 0, len(runtimeCfg.Gateway.Nodes.P2P.ICEServers))
|
||||
for _, serverCfg := range runtimeCfg.Gateway.Nodes.P2P.ICEServers {
|
||||
urls := make([]string, 0, len(serverCfg.URLs))
|
||||
for _, raw := range serverCfg.URLs {
|
||||
if v := strings.TrimSpace(raw); v != "" {
|
||||
urls = append(urls, v)
|
||||
}
|
||||
}
|
||||
if len(urls) == 0 {
|
||||
continue
|
||||
}
|
||||
out = append(out, webrtc.ICEServer{
|
||||
URLs: urls,
|
||||
Username: strings.TrimSpace(serverCfg.Username),
|
||||
Credential: serverCfg.Credential,
|
||||
})
|
||||
}
|
||||
return out
|
||||
}
|
||||
server.SetNodeP2PStatusHandler(func() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"enabled": runtimeCfg.Gateway.Nodes.P2P.Enabled,
|
||||
"transport": strings.TrimSpace(runtimeCfg.Gateway.Nodes.P2P.Transport),
|
||||
"configured_stun": append([]string(nil), runtimeCfg.Gateway.Nodes.P2P.STUNServers...),
|
||||
"configured_ice": len(runtimeCfg.Gateway.Nodes.P2P.ICEServers),
|
||||
}
|
||||
})
|
||||
switch {
|
||||
case runtimeCfg.Gateway.Nodes.P2P.Enabled && strings.EqualFold(strings.TrimSpace(runtimeCfg.Gateway.Nodes.P2P.Transport), "webrtc"):
|
||||
webrtcTransport := nodes.NewWebRTCTransport(runtimeCfg.Gateway.Nodes.P2P.STUNServers)
|
||||
webrtcTransport := nodes.NewWebRTCTransport(runtimeCfg.Gateway.Nodes.P2P.STUNServers, buildICEServers()...)
|
||||
loop.SetNodeP2PTransport(webrtcTransport)
|
||||
server.SetNodeWebRTCTransport(webrtcTransport)
|
||||
server.SetNodeP2PStatusHandler(func() map[string]interface{} {
|
||||
@@ -150,6 +172,7 @@ func gatewayCmd() {
|
||||
snapshot["enabled"] = true
|
||||
snapshot["transport"] = "webrtc"
|
||||
snapshot["configured_stun"] = append([]string(nil), runtimeCfg.Gateway.Nodes.P2P.STUNServers...)
|
||||
snapshot["configured_ice"] = len(runtimeCfg.Gateway.Nodes.P2P.ICEServers)
|
||||
return snapshot
|
||||
})
|
||||
default:
|
||||
|
||||
@@ -134,6 +134,8 @@ func statusCmd() {
|
||||
fmt.Printf(" - %s\n", key)
|
||||
}
|
||||
}
|
||||
fmt.Printf("Nodes P2P: enabled=%t transport=%s\n", cfg.Gateway.Nodes.P2P.Enabled, strings.TrimSpace(cfg.Gateway.Nodes.P2P.Transport))
|
||||
fmt.Printf("Nodes P2P ICE: stun=%d ice=%d\n", len(cfg.Gateway.Nodes.P2P.STUNServers), len(cfg.Gateway.Nodes.P2P.ICEServers))
|
||||
ns := nodes.DefaultManager().List()
|
||||
if len(ns) > 0 {
|
||||
online := 0
|
||||
@@ -163,7 +165,6 @@ func statusCmd() {
|
||||
}
|
||||
fmt.Printf("Nodes: total=%d online=%d\n", len(ns), online)
|
||||
fmt.Printf("Nodes Capabilities: run=%d model=%d camera=%d screen=%d location=%d canvas=%d\n", caps["run"], caps["model"], caps["camera"], caps["screen"], caps["location"], caps["canvas"])
|
||||
fmt.Printf("Nodes P2P: enabled=%t transport=%s\n", cfg.Gateway.Nodes.P2P.Enabled, strings.TrimSpace(cfg.Gateway.Nodes.P2P.Transport))
|
||||
if total, okCnt, avgMs, actionTop, transportTop, fallbackCnt, err := collectNodeDispatchStats(filepath.Join(workspace, "memory", "nodes-dispatch-audit.jsonl")); err == nil && total > 0 {
|
||||
fmt.Printf("Nodes Dispatch: total=%d ok=%d fail=%d avg_ms=%d\n", total, okCnt, total-okCnt, avgMs)
|
||||
if actionTop != "" {
|
||||
|
||||
@@ -25,6 +25,12 @@ func TestStatusCmdUsesActiveProviderDetails(t *testing.T) {
|
||||
cfg.Logging.Enabled = false
|
||||
cfg.Agents.Defaults.Workspace = workspace
|
||||
cfg.Agents.Defaults.Proxy = "backup"
|
||||
cfg.Gateway.Nodes.P2P.Enabled = true
|
||||
cfg.Gateway.Nodes.P2P.Transport = "webrtc"
|
||||
cfg.Gateway.Nodes.P2P.STUNServers = []string{"stun:stun.example.net:3478"}
|
||||
cfg.Gateway.Nodes.P2P.ICEServers = []config.GatewayICEConfig{
|
||||
{URLs: []string{"turn:turn.example.net:3478"}, Username: "user", Credential: "secret"},
|
||||
}
|
||||
cfg.Providers.Proxy.APIBase = "https://primary.example/v1"
|
||||
cfg.Providers.Proxy.APIKey = ""
|
||||
cfg.Providers.Proxies["backup"] = config.ProviderConfig{
|
||||
@@ -68,4 +74,10 @@ func TestStatusCmdUsesActiveProviderDetails(t *testing.T) {
|
||||
if !strings.Contains(out, "Provider API Key: ✓") {
|
||||
t.Fatalf("expected active provider api key status in output, got: %s", out)
|
||||
}
|
||||
if !strings.Contains(out, "Nodes P2P: enabled=true transport=webrtc") {
|
||||
t.Fatalf("expected nodes p2p status in output, got: %s", out)
|
||||
}
|
||||
if !strings.Contains(out, "Nodes P2P ICE: stun=1 ice=1") {
|
||||
t.Fatalf("expected nodes p2p ice summary in output, got: %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user