Files
Wormhole/internal/bridge/watchdog.go
T
rose_cat707 612d68f56f feat: Wormhole 内网穿透与反向代理网关
Go + Vue 管理台,SQLite 持久化;支持隧道/域名穿透、域名转发插件链、访客认证、
IP 规则、API Key、Docker 单镜像部署;配置通过 Web 系统设置管理,无需 YAML 文件。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 12:15:02 +08:00

68 lines
1.3 KiB
Go

package bridge
import (
"log"
"time"
"github.com/wormhole/wormhole/internal/protocol"
)
func (b *Bridge) startWatchdog() {
go func() {
ticker := time.NewTicker(WatchdogInterval)
defer ticker.Stop()
for range ticker.C {
b.runWatchdog()
}
}()
}
func (b *Bridge) runWatchdog() {
now := time.Now()
b.mu.RLock()
sessions := make([]*AgentSession, 0, len(b.agents))
for _, agent := range b.agents {
sessions = append(sessions, agent)
}
b.mu.RUnlock()
for _, agent := range sessions {
if agent.closed.Load() {
continue
}
lastPing, ok := b.cache.AgentLastPing(agent.ClientID)
if !ok {
continue
}
since := now.Sub(lastPing)
if since > HeartbeatTimeout {
log.Printf("[bridge] client %d heartbeat timeout (%v), closing", agent.ClientID, since.Round(time.Second))
agent.Close()
continue
}
if since > ServerProbeAfter {
go b.probeAgent(agent)
}
}
}
func (b *Bridge) probeAgent(agent *AgentSession) {
if agent.closed.Load() {
return
}
stream, err := agent.smux.OpenStream()
if err != nil {
return
}
defer stream.Close()
if err := protocol.WriteMessage(stream, protocol.MsgPing, nil); err != nil {
return
}
msgType, _, err := protocol.ReadMessage(stream)
if err != nil || msgType != protocol.MsgPong {
return
}
b.cache.TouchAgent(agent.ClientID)
}