diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go index 35abc4ab..d46cd090 100644 --- a/common/rpc/rpc.go +++ b/common/rpc/rpc.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "log" + "strings" "time" config "blazing/modules/config/service" @@ -20,6 +21,18 @@ type ServerHandler struct{} const kickForwardTimeout = 3 * time.Second +// A 服强关,留下僵尸在线状态:B 服可以通过 login 清理后登录。 +// login 服不可用:B 服不会放行,仍提示系统忙。 +func isDisconnectedLogicReverseClientError(err error) bool { + if err == nil { + return false + } + errText := err.Error() + return strings.Contains(errText, "websocket routine exiting") || + strings.Contains(errText, "sendRequest failed") || + strings.Contains(errText, "closed out channel") +} + // 实现踢人 func (*ServerHandler) Kick(_ context.Context, userid uint32) error { useid1, err := share.ShareManager.GetUserOnline(userid) @@ -57,6 +70,11 @@ func (*ServerHandler) Kick(_ context.Context, userid uint32) error { cool.DeleteClientOnly(useid2) return nil } + if isDisconnectedLogicReverseClientError(callErr) { + _ = share.ShareManager.DeleteUserOnline(userid) + cool.DeleteClientOnly(useid2) + return nil + } // 仍在线则返回失败,不按成功处理 return callErr diff --git a/modules/player/service/info.go b/modules/player/service/info.go index 5319c9c5..40909fa3 100644 --- a/modules/player/service/info.go +++ b/modules/player/service/info.go @@ -12,6 +12,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "time" @@ -212,6 +213,11 @@ func (s *InfoService) Kick(id uint32) error { _ = share.ShareManager.DeleteUserOnline(id) return nil } + if isDisconnectedLogicReverseClientError(callErr) { + _ = share.ShareManager.DeleteUserOnline(id) + cool.DeleteClientOnly(useid2) + return nil + } return callErr case <-time.After(3 * time.Second): // 防止异常场景下无限等待;超时不按成功处理 @@ -227,6 +233,16 @@ func (s *InfoService) Kick(id uint32) error { } } +func isDisconnectedLogicReverseClientError(err error) bool { + if err == nil { + return false + } + errText := err.Error() + return strings.Contains(errText, "websocket routine exiting") || + strings.Contains(errText, "sendRequest failed") || + strings.Contains(errText, "closed out channel") +} + // saveToLocalFile 兜底保存:将数据写入本地lose文件夹 func (s *InfoService) saveToLocalFile(player *model.PlayerInfo, err error) { // 1. 创建lose文件夹(如果不存在)