refactor: 重构运行时ID组合逻辑

将硬编码的 ID 组合逻辑(100000*OnlineID + Port)提取为通用函数 ComposeRuntimeID,
使用 16 位位移掩码优化,并新增辅助方法与类型转换。同时修复踢人流程中的资源清理问题。
This commit is contained in:
xinian
2026-04-28 04:03:13 +08:00
parent deae6d371e
commit 7d49aaa212
10 changed files with 59 additions and 15 deletions

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
// cool config
@@ -50,7 +49,11 @@ type ServerList struct {
}
func (s *ServerList) GetID() string {
return gconv.String(100000*s.OnlineID + s.Port)
return RuntimeIDString(s.OnlineID, s.Port)
}
func (s *ServerList) RuntimeID() uint32 {
return ComposeRuntimeID(s.OnlineID, s.Port)
}
// OSS相关配置

View File

@@ -0,0 +1,22 @@
package coolconfig
import "github.com/gogf/gf/v2/util/gconv"
const runtimeIDPortBits = 16
const runtimeIDPortMask uint32 = 0xFFFF
// ComposeRuntimeID 将 serverID 和 port 组合成运行时复合 ID。
// 高 16 位保存 serverID低 16 位保存 port。
func ComposeRuntimeID(serverID, port uint32) uint32 {
return ((serverID & runtimeIDPortMask) << runtimeIDPortBits) | (port & runtimeIDPortMask)
}
// SplitRuntimeID 将运行时复合 ID 拆分为 serverID 和 port。
func SplitRuntimeID(runtimeID uint32) (serverID, port uint32) {
return runtimeID >> runtimeIDPortBits, runtimeID & runtimeIDPortMask
}
// RuntimeIDString 返回运行时复合 ID 的字符串形式。
func RuntimeIDString(serverID, port uint32) string {
return gconv.String(ComposeRuntimeID(serverID, port))
}

View File

@@ -1,25 +1,27 @@
package cool
import "blazing/cool/coolconfig"
// 存值示例
func AddClient(id uint32, client *ClientHandler) {
// 普通mapClientmap[id] = client
Clientmap.Store(id, client) // sync.Map存值
}
// 清理指定clientuid=100000*onlineID+port
// 清理指定 client高 16 位 serverID低 16 位 port
func DeleteClientOnly(uid uint32) {
Clientmap.Delete(uid)
}
// 清理指定clientonlineID+port
// 清理指定 client由 serverID 和 port 组合
func DeleteClient(id, port uint32) {
Clientmap.Delete(100000*id + port)
Clientmap.Delete(coolconfig.ComposeRuntimeID(id, port))
}
// 取值示例
func GetClient(id, port uint32) (*ClientHandler, bool) {
// 普通mapclient, ok := Clientmap[id]
val, ok := Clientmap.Load(100000*id + port) // sync.Map取值
val, ok := Clientmap.Load(coolconfig.ComposeRuntimeID(id, port)) // sync.Map取值
if !ok {
return nil, false
}

View File

@@ -3,6 +3,7 @@ package rpc
import (
"blazing/common/data/share"
"blazing/cool"
"blazing/cool/coolconfig"
"context"
"fmt"
@@ -190,7 +191,7 @@ func setupLogicReverseClient(ctx context.Context, revClient cool.ClientHandler)
return err
}
key := 100000*id + port
key := coolconfig.ComposeRuntimeID(id, port)
go func() {
<-ctx.Done()
cool.DeleteClientOnly(key)
@@ -210,6 +211,6 @@ func registerReverseLogicClient(ctx context.Context, id, port uint32) error {
if ok && aa != nil { //如果已经存在且这个端口已经被存过
aa.QuitSelf(0)
}
cool.AddClient(100000*id+port, &revClient)
cool.AddClient(coolconfig.ComposeRuntimeID(id, port), &revClient)
return nil
}

View File

@@ -81,7 +81,7 @@ func Start() {
controller.Maincontroller.RPCClient = rpcClient //将RPC赋值Start
controller.Maincontroller.UID = gconv.Uint32(cool.Config.ServerInfo.GetID()) //赋值服务器ID
controller.Maincontroller.UID = cool.Config.ServerInfo.RuntimeID() //赋值服务器复合ID
controller.Init(true)
xmlres.Initfile()

View File

@@ -13,8 +13,6 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
@@ -983,6 +981,5 @@ func isCoordinator() bool {
}
func localRuntimeServerID() uint32 {
id, _ := strconv.ParseUint(strings.TrimSpace(cool.Config.ServerInfo.GetID()), 10, 32)
return uint32(id)
return cool.Config.ServerInfo.RuntimeID()
}

View File

@@ -478,7 +478,8 @@ func (player1 *Player) Kick(isquit bool) {
timeout := false
select {
case <-CloseChan:
// 正常流程:连接关闭回调已执行CloseChan 被关闭
// 连接关闭后同步落盘,保证踢人链路返回前完成保存。
player1.SaveOnDisconnect()
case <-time.After(kickTimeout):
timeout = true
}

View File

@@ -34,7 +34,13 @@ type QuitSReq struct {
func (this *ServerController) Quit(ctx context.Context, req *QuitSReq) (res *cool.BaseRes, err error) {
res = &cool.BaseRes{}
serv := service.NewServerService().GetServerID(req.ID)
serverService := service.NewServerService()
if req.Code != 0 {
if err = serverService.SetServerOpen(req.ID, 0); err != nil {
return res, err
}
}
serv := serverService.GetServerID(req.ID)
aa, ok := cool.GetClient(serv.OnlineID, serv.Port)
if ok && aa != nil { //如果已经存在且这个端口已经被存过

View File

@@ -167,6 +167,15 @@ func (s *ServerService) StartUPdate(OnlineID uint16, isinstall int) model.Server
return tttt
}
func (s *ServerService) SetServerOpen(OnlineID uint32, isOpen uint8) error {
m := cool.DBM(s.Model).Where("online_id", OnlineID)
var tttt model.ServerList
m.Scan(&tttt)
tttt.IsOpen = isOpen
_, err := m.Save(tttt)
return err
}
func (s *ServerService) SetServerID(OnlineID uint32, Port uint32) error {
m := cool.DBM(s.Model).Where("online_id", OnlineID)
var tttt model.ServerList

View File

@@ -190,6 +190,7 @@ func (s *InfoService) Kick(id uint32) error {
if !ok || cl == nil {
// 目标服务器不在线,清理僵尸在线标记并视为成功
_ = share.ShareManager.DeleteUserOnline(id)
cool.DeleteClientOnly(useid1)
return nil
}
@@ -211,6 +212,7 @@ func (s *InfoService) Kick(id uint32) error {
}
if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil {
_ = share.ShareManager.DeleteUserOnline(id)
cool.DeleteClientOnly(useid2)
return nil
}
if isDisconnectedLogicReverseClientError(callErr) {
@@ -227,6 +229,7 @@ func (s *InfoService) Kick(id uint32) error {
}
if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil {
_ = share.ShareManager.DeleteUserOnline(id)
cool.DeleteClientOnly(useid2)
return nil
}
return fmt.Errorf("kick timeout, user still online: uid=%d server=%d", id, useid2)