mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-11 01:36:37 +08:00
fix(openflare): refresh WS read deadline on JSON pong; capture frpc stderr
- read_pump: 收到客户端 JSON {"type":"pong"} 时调用 conn.SetReadDeadline 刷新
服务端读超时。修复前,服务端仅在 WebSocket 协议层 Pong 帧时刷新 deadline,
而客户端使用 JSON 应用层 pong 回复,导致服务端 90s 后超时关闭连接,
客户端收到 EOF 并触发无限重连循环。在 Cloudflare 代理场景下,
100s 空闲超时进一步加剧了此问题。
- frpc/manager: 捕获 frpc 子进程 stderr 并在进程异常退出时
将其内容记录到结构化日志 stderr 字段,便于诊断 exit status 1 的
具体原因(如配置格式错误、Auth Token 失败、relay 服务端不可达等)。
This commit is contained in:
@@ -192,6 +192,8 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
|||||||
ensureNoOrphanProcess(pidPath)
|
ensureNoOrphanProcess(pidPath)
|
||||||
|
|
||||||
cmd := exec.CommandContext(procCtx, m.cfg.FrpcPath, "-c", configPath) //nolint:gosec // FrpcPath and configPath are managed trusted locations
|
cmd := exec.CommandContext(procCtx, m.cfg.FrpcPath, "-c", configPath) //nolint:gosec // FrpcPath and configPath are managed trusted locations
|
||||||
|
var stderrBuf bytes.Buffer
|
||||||
|
cmd.Stderr = &stderrBuf
|
||||||
|
|
||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
proc.Cmd = cmd
|
proc.Cmd = cmd
|
||||||
@@ -213,10 +215,15 @@ func (m *Manager) restartProcess(ctx context.Context, relayID string, configPath
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stderrOutput := strings.TrimSpace(stderrBuf.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
proc.LastError = err.Error()
|
proc.LastError = err.Error()
|
||||||
proc.Status = "error"
|
proc.Status = "error"
|
||||||
slog.Error("frpc process exited unexpectedly", "relay_id", relayID, "error", err)
|
if stderrOutput != "" {
|
||||||
|
slog.Error("frpc process exited unexpectedly", "relay_id", relayID, "error", err, "stderr", stderrOutput)
|
||||||
|
} else {
|
||||||
|
slog.Error("frpc process exited unexpectedly", "relay_id", relayID, "error", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
proc.Status = "stopped"
|
proc.Status = "stopped"
|
||||||
proc.LastError = "exited unexpectedly with code 0"
|
proc.LastError = "exited unexpectedly with code 0"
|
||||||
|
|||||||
@@ -42,6 +42,13 @@ func runReadPump(
|
|||||||
case messageTypePing:
|
case messageTypePing:
|
||||||
_ = sendPong(nodeID)
|
_ = sendPong(nodeID)
|
||||||
case clientPongType:
|
case clientPongType:
|
||||||
|
// Refresh read deadline when the client replies with a JSON pong.
|
||||||
|
// This keeps the connection alive when the WebSocket is proxied
|
||||||
|
// through Cloudflare, which enforces a 100-second idle timeout on
|
||||||
|
// the TCP stream. Without this refresh, the server's 90-second read
|
||||||
|
// deadline expires and terminates the connection even though the
|
||||||
|
// client is actively responding to pings.
|
||||||
|
_ = conn.SetReadDeadline(time.Now().Add(wsReadDeadline))
|
||||||
default:
|
default:
|
||||||
slog.Debug(logLabel+" unsupported message", "node_id", nodeID, "type", message.Type)
|
slog.Debug(logLabel+" unsupported message", "node_id", nodeID, "type", message.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user