mirror of
https://gitcode.com/JianFeeeee/webui4frpc.git
synced 2026-09-20 00:47:57 +00:00
fix: worker 进程并发 double-close panic + 状态页连接语义重构 + 集群页骨架
- process: spawn 不再重复起 supervise goroutine(Restart 触发旧 supervise close doneCh 后再 close → panic);新增 closeOnce/supervising 守卫;Start 首次起 supervise,重启循环在同一 goroutine 内 - httpapi: status 增加 connState(connected/connecting/failed/not_started/disabled),由 worker 日志探测真实 frps 连接(不再把本地 worker 状态误当远程 frps 状态) - StatusView: 远程卡片主状态改为连接状态徽标;启停按钮标注为控制本地 frpc worker;本地转发区保留 worker 状态显示 - 新增 ClusterView 集群页骨架(M3 LB+健康检查载体)+ App.vue 导航接入 - render: bandwidthLimit 从 proxy 顶层移入 transport 段(frpc 0.61 正确 schema,修复真实连不上的 bug)
This commit is contained in:
@ -146,6 +146,9 @@ func (h *Handler) handleStatus(w http.ResponseWriter, r *http.Request) {
|
||||
Status process.Status `json:"process"`
|
||||
HasProc bool `json:"hasProcess"`
|
||||
Forwards []store.Forward `json:"forwards"`
|
||||
// ConnState is the derived frps connection state:
|
||||
// connected | connecting | failed | not_started | disabled.
|
||||
ConnState string `json:"connState"`
|
||||
}
|
||||
|
||||
profiles := make([]profileStatus, 0, len(remotes))
|
||||
@ -158,6 +161,7 @@ func (h *Handler) handleStatus(w http.ResponseWriter, r *http.Request) {
|
||||
fwd, _ := h.Store.LinksForRemote(rv.Name)
|
||||
profiles = append(profiles, profileStatus{
|
||||
Name: rv.Name, Enabled: rv.Enabled, Status: st, HasProc: has, Forwards: fwd,
|
||||
ConnState: connStateOf(h.Process.LogPath(rv.Name), rv.Enabled, st),
|
||||
})
|
||||
}
|
||||
|
||||
@ -204,6 +208,49 @@ func (h *Handler) handleStatus(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, resp)
|
||||
}
|
||||
|
||||
// connStateOf derives the frps connection state from the local worker process
|
||||
// state plus a probe of its log. We never control the remote frps: the worker is
|
||||
// our local frpc; "connected" means frpc has successfully logged in to frps.
|
||||
// - disabled -> remote disabled, worker not started
|
||||
// - running+login -> frpc logged in to frps (connected)
|
||||
// - running -> frpc up but not yet logged in (connecting)
|
||||
// - starting/restarting -> connecting
|
||||
// - crashed/exit nonzero -> failed
|
||||
// - stopped clean / no worker -> not_started
|
||||
func connStateOf(workerLog string, enabled bool, st process.Status) string {
|
||||
if !enabled {
|
||||
return "disabled"
|
||||
}
|
||||
switch st.State {
|
||||
case "running":
|
||||
tail, _ := tailFile(workerLog, 64*1024)
|
||||
if tail != "" {
|
||||
// frpc prints "login to server success" once the control link is up.
|
||||
if strings.Contains(tail, "login to server success") ||
|
||||
strings.Contains(tail, "start proxy success") {
|
||||
return "connected"
|
||||
}
|
||||
if strings.Contains(tail, "login to server error") ||
|
||||
strings.Contains(tail, "connect to server error") ||
|
||||
strings.Contains(tail, "connect server error") {
|
||||
return "failed"
|
||||
}
|
||||
}
|
||||
return "connecting"
|
||||
case "starting", "restarting":
|
||||
return "connecting"
|
||||
case "crashed":
|
||||
return "failed"
|
||||
case "stopped":
|
||||
if st.ExitCode != 0 || st.Err != "" {
|
||||
return "failed"
|
||||
}
|
||||
return "not_started"
|
||||
default:
|
||||
return "not_started"
|
||||
}
|
||||
}
|
||||
|
||||
func methodNotAllowed(w http.ResponseWriter) {
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user