Merge pull request #28 from Sagit-chu/opencode/lucky-eagle

fix(gost): process WebSocket commands concurrently to prevent diagnos…
This commit is contained in:
sagit
2026-02-05 14:25:24 +08:00
committed by GitHub
2 changed files with 40 additions and 5 deletions
+6
View File
@@ -2,11 +2,17 @@ package socket
import ( import (
"os" "os"
"sync"
"github.com/go-gost/x/config" "github.com/go-gost/x/config"
) )
// configMutex 保护配置文件的并发写入
var configMutex sync.Mutex
func saveConfig() { func saveConfig() {
configMutex.Lock()
defer configMutex.Unlock()
file := "gost.json" file := "gost.json"
+34 -5
View File
@@ -466,7 +466,13 @@ func (w *WebSocketReporter) handleReceivedMessage(messageType int, message []byt
} }
if cmdMsg.Type != "call" { if cmdMsg.Type != "call" {
w.routeCommand(cmdMsg) // TcpPing 诊断命令异步执行,避免阻塞其他命令
// 其他状态变更命令保持同步,确保顺序执行
if cmdMsg.Type == "TcpPing" {
go w.routeCommand(cmdMsg)
} else {
w.routeCommand(cmdMsg)
}
} }
} else { } else {
// 处理普通消息 // 处理普通消息
@@ -477,7 +483,13 @@ func (w *WebSocketReporter) handleReceivedMessage(messageType int, message []byt
return return
} }
if cmdMsg.Type != "call" { if cmdMsg.Type != "call" {
w.routeCommand(cmdMsg) // TcpPing 诊断命令异步执行,避免阻塞其他命令
// 其他状态变更命令保持同步,确保顺序执行
if cmdMsg.Type == "TcpPing" {
go w.routeCommand(cmdMsg)
} else {
w.routeCommand(cmdMsg)
}
} }
} }
@@ -497,6 +509,7 @@ func (w *WebSocketReporter) routeCommand(cmd CommandMessage) {
fmt.Println("🔔 收到命令: ", string(jsonBytes)) fmt.Println("🔔 收到命令: ", string(jsonBytes))
var err error var err error
var response CommandResponse var response CommandResponse
var needSaveConfig bool // 标记是否需要保存配置(只有状态变更命令才需要)
// 传递 requestId // 传递 requestId
response.RequestId = cmd.RequestId response.RequestId = cmd.RequestId
@@ -506,65 +519,81 @@ func (w *WebSocketReporter) routeCommand(cmd CommandMessage) {
case "AddService": case "AddService":
err = w.handleAddService(cmd.Data) err = w.handleAddService(cmd.Data)
response.Type = "AddServiceResponse" response.Type = "AddServiceResponse"
needSaveConfig = true
case "UpdateService": case "UpdateService":
err = w.handleUpdateService(cmd.Data) err = w.handleUpdateService(cmd.Data)
response.Type = "UpdateServiceResponse" response.Type = "UpdateServiceResponse"
needSaveConfig = true
case "DeleteService": case "DeleteService":
err = w.handleDeleteService(cmd.Data) err = w.handleDeleteService(cmd.Data)
response.Type = "DeleteServiceResponse" response.Type = "DeleteServiceResponse"
needSaveConfig = true
case "PauseService": case "PauseService":
err = w.handlePauseService(cmd.Data) err = w.handlePauseService(cmd.Data)
response.Type = "PauseServiceResponse" response.Type = "PauseServiceResponse"
needSaveConfig = true
case "ResumeService": case "ResumeService":
err = w.handleResumeService(cmd.Data) err = w.handleResumeService(cmd.Data)
response.Type = "ResumeServiceResponse" response.Type = "ResumeServiceResponse"
needSaveConfig = true
// Chain 相关命令 // Chain 相关命令
case "AddChains": case "AddChains":
err = w.handleAddChain(cmd.Data) err = w.handleAddChain(cmd.Data)
response.Type = "AddChainsResponse" response.Type = "AddChainsResponse"
needSaveConfig = true
case "UpdateChains": case "UpdateChains":
err = w.handleUpdateChain(cmd.Data) err = w.handleUpdateChain(cmd.Data)
response.Type = "UpdateChainsResponse" response.Type = "UpdateChainsResponse"
needSaveConfig = true
case "DeleteChains": case "DeleteChains":
err = w.handleDeleteChain(cmd.Data) err = w.handleDeleteChain(cmd.Data)
response.Type = "DeleteChainsResponse" response.Type = "DeleteChainsResponse"
needSaveConfig = true
// Limiter 相关命令 // Limiter 相关命令
case "AddLimiters": case "AddLimiters":
err = w.handleAddLimiter(cmd.Data) err = w.handleAddLimiter(cmd.Data)
response.Type = "AddLimitersResponse" response.Type = "AddLimitersResponse"
needSaveConfig = true
case "UpdateLimiters": case "UpdateLimiters":
err = w.handleUpdateLimiter(cmd.Data) err = w.handleUpdateLimiter(cmd.Data)
response.Type = "UpdateLimitersResponse" response.Type = "UpdateLimitersResponse"
needSaveConfig = true
case "DeleteLimiters": case "DeleteLimiters":
err = w.handleDeleteLimiter(cmd.Data) err = w.handleDeleteLimiter(cmd.Data)
response.Type = "DeleteLimitersResponse" response.Type = "DeleteLimitersResponse"
needSaveConfig = true
// TCP Ping 诊断命令 // TCP Ping 诊断命令(只读,不需要保存配置)
case "TcpPing": case "TcpPing":
var tcpPingResult TcpPingResponse var tcpPingResult TcpPingResponse
tcpPingResult, err = w.handleTcpPing(cmd.Data) tcpPingResult, err = w.handleTcpPing(cmd.Data)
response.Type = "TcpPingResponse" response.Type = "TcpPingResponse"
response.Data = tcpPingResult response.Data = tcpPingResult
// needSaveConfig = false (默认值)
// Protocol blocking switches // Protocol blocking switches
case "SetProtocol": case "SetProtocol":
err = w.handleSetProtocol(cmd.Data) err = w.handleSetProtocol(cmd.Data)
response.Type = "SetProtocolResponse" response.Type = "SetProtocolResponse"
needSaveConfig = true
default: default:
err = fmt.Errorf("未知命令类型: %s", cmd.Type) err = fmt.Errorf("未知命令类型: %s", cmd.Type)
response.Type = "UnknownCommandResponse" response.Type = "UnknownCommandResponse"
} }
// 只有状态变更命令才保存配置
if needSaveConfig {
saveConfig()
}
// 发送响应 // 发送响应
if err != nil { if err != nil {
saveConfig()
response.Success = false response.Success = false
response.Message = err.Error() response.Message = err.Error()
} else { } else {
saveConfig()
response.Success = true response.Success = true
response.Message = "OK" response.Message = "OK"
} }