Files
OpenFlare/openflared/internal/flared/runner.go
T
2026-06-01 09:03:55 +08:00

85 lines
1.8 KiB
Go

package flared
import (
"context"
"log/slog"
"time"
"openflare-flared/internal/config"
"openflare-flared/internal/frpc"
"openflare-flared/internal/heartbeat"
"openflare-flared/internal/httpclient"
"openflare-flared/internal/sync"
"openflare-flared/internal/wsclient"
)
type Runner struct {
Config *config.Config
HeartbeatService *heartbeat.Service
FrpcManager *frpc.Manager
SyncService *sync.Service
WebSocketService *wsclient.Client
HttpClient *httpclient.Client
}
func (r *Runner) Run(ctx context.Context) error {
// Start background services
go r.HeartbeatService.Run(ctx)
go r.SyncService.Run(ctx)
// WebSocket reconnection loop
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
conn, err := r.WebSocketService.Connect(ctx)
if err != nil {
slog.Error("flared ws connect failed, will retry", "error", err)
r.sleepContext(ctx, 5*time.Second)
continue
}
r.handleConnection(ctx, conn)
_ = conn.Close()
slog.Info("flared ws connection closed, reconnecting...")
r.sleepContext(ctx, 2*time.Second)
}
}
func (r *Runner) handleConnection(ctx context.Context, conn *wsclient.Connection) {
for {
select {
case <-ctx.Done():
return
default:
}
msg, err := conn.Receive()
if err != nil {
slog.Error("flared ws receive failed", "error", err)
return
}
switch msg.Type {
case "ping":
_ = conn.SendPong()
case "active_config":
// Server notifies there is a new config available
slog.Info("received config update notification from server")
r.SyncService.Trigger()
default:
slog.Debug("ignored unknown ws message type", "type", msg.Type)
}
}
}
func (r *Runner) sleepContext(ctx context.Context, d time.Duration) {
select {
case <-ctx.Done():
case <-time.After(d):
}
}