From a023c28dc8612e4a7c4f4b28853713b5ee05f4f0 Mon Sep 17 00:00:00 2001 From: liuxiaobo <1224730913@qq.com> Date: Tue, 17 Jun 2025 12:48:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/baseroom/baseRoom.go | 2 +- common/baseroom/hundredRoom.go | 2 +- common/baseroom/interface.go | 1 - common/userBindService/userService.go | 79 +++++++++++---------------- server/colorgame/room/c2s.go | 21 +++++-- server/colorgame/room/colorPlayer.go | 10 +--- server/colorgame/room/colorRoom.go | 1 + server/colorgame/server/processor.go | 3 +- server/colorgame/server/service.go | 2 + server/match/server/match.go | 6 ++ server/match/server/processor.go | 3 +- server/match/server/service.go | 2 + 12 files changed, 65 insertions(+), 67 deletions(-) diff --git a/common/baseroom/baseRoom.go b/common/baseroom/baseRoom.go index 56013ac..128b763 100644 --- a/common/baseroom/baseRoom.go +++ b/common/baseroom/baseRoom.go @@ -159,7 +159,7 @@ func (r *BaseRoom[Seat]) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message user.Robot().OnMessage(msgId, msg) } else { iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg) - _ = r.srv.SendByTopic(user.GateTopicName(), iMsg) + _ = r.srv.SendByServiceId(int(pb.ServiceTypeId_STI_Gate), iMsg) } } diff --git a/common/baseroom/hundredRoom.go b/common/baseroom/hundredRoom.go index dd3764a..00d5596 100644 --- a/common/baseroom/hundredRoom.go +++ b/common/baseroom/hundredRoom.go @@ -114,7 +114,7 @@ func (r *HundredRoom) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) { user.Robot().OnMessage(msgId, msg) } else { iMsg := ipb.MakeMsgEx(r.room.srv.Name(), 0, user.Id(), int32(msgId), msg) - _ = r.room.srv.SendByTopic(user.GateTopicName(), iMsg) + _ = r.room.srv.SendByServiceId(int(pb.ServiceTypeId_STI_Gate), iMsg) } } diff --git a/common/baseroom/interface.go b/common/baseroom/interface.go index fbca3d0..268adbb 100644 --- a/common/baseroom/interface.go +++ b/common/baseroom/interface.go @@ -31,7 +31,6 @@ type IPlayer interface { Id() int64 Robot() IRobot IsRobot() bool - GateTopicName() string RoomId() int } diff --git a/common/userBindService/userService.go b/common/userBindService/userService.go index 3e6afdf..6eb4cc1 100644 --- a/common/userBindService/userService.go +++ b/common/userBindService/userService.go @@ -10,7 +10,6 @@ import ( "github.com/fox/fox/log" "github.com/fox/fox/xrand" "github.com/go-redis/redis/v8" - "time" ) const ( @@ -45,7 +44,7 @@ func NewUserBindService(rdb *redis.Client, etcdRegistry *etcd.Registry[etcd.Serv } func (m *UserBindService) makeRedisKey(userId int64) string { - return fmt.Sprintf("%s:%s", prefix, userId) + return fmt.Sprintf("%s:%d", prefix, userId) } func (m *UserBindService) makeRedisSubKey(typeId pb.ServiceTypeId) string { return typeId.String() @@ -76,7 +75,7 @@ func (m *UserBindService) DelUserService(userId int64, typeId pb.ServiceTypeId) func (m *UserBindService) SaveUserService(userId int64, typeId pb.ServiceTypeId, serviceName string) { key := m.makeRedisKey(userId) subKey := m.makeRedisSubKey(typeId) - m.rdb.HSet(context.Background(), key, subKey, serviceName, 2*24*time.Hour) + m.rdb.HSet(context.Background(), key, subKey, serviceName) } // 从etcd中检查节点是否有效,如果有game1(旧服),game2(新服),都算有效,但是旧服会拒绝新玩家进入, @@ -84,13 +83,11 @@ func (m *UserBindService) SaveUserService(userId int64, typeId pb.ServiceTypeId, func (m *UserBindService) findServiceNodeByServiceName(serviceName string) (*etcd.ServiceNode, bool) { var sNode *etcd.ServiceNode valid := false - m.etcdRegistry.GetNodes().Range(func(k, v interface{}) bool { - if node, ok := v.(etcd.ServiceNode); ok { - if node.Name == serviceName { - valid = true - sNode = &node - return false - } + m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool { + if node.Name == serviceName { + valid = true + sNode = node + return false } return true }) @@ -98,35 +95,41 @@ func (m *UserBindService) findServiceNodeByServiceName(serviceName string) (*etc } func (m *UserBindService) stringAllServiceNode() string { - var nodes []any - m.etcdRegistry.GetNodes().Range(func(_, value any) bool { - nodes = append(nodes, value) + var nodes []*etcd.ServiceNode + m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool { + nodes = append(nodes, node) return true }) return utils.JsonMarshal(nodes) } -// 从etcd中找可用服务节点随机选择一个 -func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.ServiceNode, error) { +// 获取最新的节点 +func (m *UserBindService) getLatestServiceNode(typeId pb.ServiceTypeId) []etcd.ServiceNode { var nodes []etcd.ServiceNode var version string - m.etcdRegistry.GetNodes().Range(func(_, value any) bool { - node, ok := value.(etcd.ServiceNode) - if ok && node.TypeId == int(typeId) { + // 查找最新版本号 + m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool { + if node.TypeId == int(typeId) { if version < node.Version { version = node.Version } } return true }) - m.etcdRegistry.GetNodes().Range(func(_, value any) bool { - if node, ok := value.(etcd.ServiceNode); ok && node.TypeId == int(typeId) { + m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool { + if node.TypeId == int(typeId) { if version == node.Version { - nodes = append(nodes, node) + nodes = append(nodes, *node) } } return true }) + return nodes +} + +// 从etcd中找可用服务节点随机选择一个 +func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.ServiceNode, error) { + var nodes = m.getLatestServiceNode(typeId) if len(nodes) == 0 { return nil, fmt.Errorf("not found service node.type id:%v. all node:%v", typeId, m.stringAllServiceNode()) } @@ -137,25 +140,7 @@ func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.Servic // 从etcd中hash一个服务节点。不需要保存玩家在哪个服务。 // 该服务是类似于db服这种有序操作的hash服 func (m *UserBindService) HashServiceNode(typeId pb.ServiceTypeId, uid int64) (*etcd.ServiceNode, error) { - var nodes []etcd.ServiceNode - var version string - m.etcdRegistry.GetNodes().Range(func(_, value any) bool { - node, ok := value.(etcd.ServiceNode) - if ok && node.TypeId == int(typeId) { - if version < node.Version { - version = node.Version - } - } - return true - }) - m.etcdRegistry.GetNodes().Range(func(_, value any) bool { - if node, ok := value.(etcd.ServiceNode); ok && node.TypeId == int(typeId) { - if version == node.Version { - nodes = append(nodes, node) - } - } - return true - }) + var nodes = m.getLatestServiceNode(typeId) if len(nodes) == 0 { return nil, fmt.Errorf("not found service node.type id:%v. all node:%v", typeId, m.stringAllServiceNode()) } @@ -184,7 +169,9 @@ func (m *UserBindService) FindServiceNode(typeId pb.ServiceTypeId, userId int64) return nil, err } // log.DebugF("etcd中随机一个服务节点:%s", node.Name) - m.rdb.HSet(context.Background(), m.makeRedisKey(userId), node.Name, 2*24*time.Hour) + if m.CheckServiceNodeStateType(typeId) == etcd.SNST_Stateful { + m.SaveUserService(userId, typeId, node.Name) + } return node, nil } @@ -196,12 +183,10 @@ func (m *UserBindService) RangeUserAllServiceNode(userId int64, proc func(node * return } if len(maps) > 0 { - m.etcdRegistry.GetNodes().Range(func(k, v interface{}) bool { - if node, ok := v.(etcd.ServiceNode); ok { - if _, ok = maps[node.Name]; ok { - if !proc(&node) { - return false - } + m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool { + if _, ok := maps[node.Name]; ok { + if !proc(node) { + return false } } return true diff --git a/server/colorgame/room/c2s.go b/server/colorgame/room/c2s.go index 31c57da..2b8ce6d 100644 --- a/server/colorgame/room/c2s.go +++ b/server/colorgame/room/c2s.go @@ -3,6 +3,7 @@ package room import ( "game/common/proto/pb" "github.com/fox/fox/ipb" + "github.com/fox/fox/log" ) func (rm *ColorRoom) checkEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom) pb.ErrCode { @@ -28,6 +29,7 @@ func (rm *ColorRoom) enterRoom(user *ColorPlayer) { user.resetData() } rm.notifyColorRoomInfo(user) + log.Debug(rm.Log("玩家:%v进入房间", user.ID)) } func (rm *ColorRoom) onEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom) { @@ -43,19 +45,20 @@ func (rm *ColorRoom) onEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req * func (rm *ColorRoom) checkLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqLeaveRoom) pb.ErrCode { _ = iMsg _ = req + if user.totalBet == 0 { + return pb.ErrCode_OK + } if rm.status >= pb.ColorGameStatus_CGS_Settle || rm.status < pb.ColorGameStatus_CGS_Betting { return pb.ErrCode_OK } - if user.totalBet == 0 { - return pb.ErrCode_NotLeaveRoom - } - return pb.ErrCode_OK + return pb.ErrCode_NotLeaveRoom } func (rm *ColorRoom) leaveRoom(user *ColorPlayer) { rm.DelPlayer(user.Id()) rm.userMgr.Del(user.ID) rm.bindService.DelUserService(user.ID, pb.ServiceTypeId_STI_ColorGame) + log.Debug(rm.Log("玩家:%v离开房间", user.ID)) } func (rm *ColorRoom) onLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqLeaveRoom) { @@ -63,9 +66,15 @@ func (rm *ColorRoom) onLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req * rm.SendMsg(user, pb.MsgId_RspEnterRoomId, &pb.RspEnterRoom{Code: code}) if code == pb.ErrCode_OK { rm.leaveRoom(user) - return } - return +} + +func (rm *ColorRoom) onUserOffline(user *ColorPlayer, iMsg *ipb.InternalMsg, ntf *pb.NtfUserOffline) { + _ = ntf + code := rm.checkLeaveRoom(user, iMsg, &pb.ReqLeaveRoom{}) + if code == pb.ErrCode_OK { + rm.leaveRoom(user) + } } func (rm *ColorRoom) checkBet(user *ColorPlayer, _ *ipb.InternalMsg, req *pb.ReqColorBetting) pb.ErrCode { diff --git a/server/colorgame/room/colorPlayer.go b/server/colorgame/room/colorPlayer.go index 73c708c..b87061b 100644 --- a/server/colorgame/room/colorPlayer.go +++ b/server/colorgame/room/colorPlayer.go @@ -9,8 +9,7 @@ import ( type ColorPlayer struct { *user.User *user.UserResources - gateTopicName string - roomId int + roomId int notBetCount int // 不投注局数 totalBet int64 // 总下注金额 @@ -18,11 +17,10 @@ type ColorPlayer struct { settleMsg *pb.NtfColorSettle // 本局结算消息 } -func NewColorPlayer(gateTopicName string, roomId int, u *user.User, res *user.UserResources) *ColorPlayer { +func NewColorPlayer(roomId int, u *user.User, res *user.UserResources) *ColorPlayer { return &ColorPlayer{ User: u, UserResources: res, - gateTopicName: gateTopicName, roomId: roomId, } } @@ -39,10 +37,6 @@ func (p *ColorPlayer) IsRobot() bool { return false } -func (p *ColorPlayer) GateTopicName() string { - return p.gateTopicName -} - func (p *ColorPlayer) RoomId() int { return p.roomId } diff --git a/server/colorgame/room/colorRoom.go b/server/colorgame/room/colorRoom.go index 414ab7a..bef7812 100644 --- a/server/colorgame/room/colorRoom.go +++ b/server/colorgame/room/colorRoom.go @@ -73,6 +73,7 @@ func (rm *ColorRoom) OnInit() { pb.MsgId_ReqColorBettingId: {pb.ReqColorBetting{}, rm.onBet}, pb.MsgId_ReqEnterRoomId: {pb.ReqEnterRoom{}, rm.onEnterRoom}, pb.MsgId_ReqLeaveRoomId: {pb.ReqLeaveRoom{}, rm.onLeaveRoom}, + pb.MsgId_NtfUserOfflineId: {pb.NtfUserOffline{}, rm.onUserOffline}, }) rm.RegisterTimerMessages(processor.RegisterTimerMetas{ TtGameStart: rm.gameStart, diff --git a/server/colorgame/server/processor.go b/server/colorgame/server/processor.go index a1aee0f..83c30d8 100644 --- a/server/colorgame/server/processor.go +++ b/server/colorgame/server/processor.go @@ -7,7 +7,6 @@ import ( "github.com/fox/fox/ipb" "github.com/fox/fox/ksync" "github.com/fox/fox/processor" - "github.com/fox/fox/service" ) const ( @@ -31,7 +30,7 @@ func (s *ColorService) onEnterRoom(iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom) } // 切回服务协程处理业务逻辑 s.RunOnce(func() { - colorUser := room.NewColorPlayer(service.TopicEx(iMsg.ServiceName), s.room.Id(), &us.User, &us.UserResources) + colorUser := room.NewColorPlayer(s.room.Id(), &us.User, &us.UserResources) s.playerMgr.Add(colorUser) _ = s.room.Dispatch(colorUser, iMsg.MsgId, iMsg, req) }) diff --git a/server/colorgame/server/service.go b/server/colorgame/server/service.go index c969e89..1471499 100644 --- a/server/colorgame/server/service.go +++ b/server/colorgame/server/service.go @@ -6,6 +6,7 @@ import ( "game/common/gameService" "game/common/proto/pb" "game/common/serviceName" + "game/common/topicName" "game/server/colorgame/config" "game/server/colorgame/room" "github.com/fox/fox/ipb" @@ -59,6 +60,7 @@ func newColorService(serviceId int) service.IService { TypeId: int(pb.ServiceTypeId_STI_ColorGame), Version: config.Cfg.BuildDate, }, &config.Cfg.Redis) + _ = s.GameService.Subscribe(topicName.UserOffline) s.initProcessor() s.playerMgr = baseroom.NewPlayerMgr(nil) diff --git a/server/match/server/match.go b/server/match/server/match.go index 191129e..dd0d7f7 100644 --- a/server/match/server/match.go +++ b/server/match/server/match.go @@ -58,3 +58,9 @@ func (s *MatchService) onMatchRoom(iMsg *ipb.InternalMsg, req *pb.ReqMatchRoom) s.SendServiceMsg(pb.ServiceTypeId_STI_Gate, iMsg.UserId, int32(pb.MsgId_RspMatchRoomId), rsp) }, nil) } + +// 匹配房间 +func (s *MatchService) onUserOffline(iMsg *ipb.InternalMsg, ntf *pb.NtfUserOffline) { + _ = iMsg + log.DebugF(s.Log("收到玩家下线消息:%v,从匹配队列中移除该玩家", ntf.UserId)) +} diff --git a/server/match/server/processor.go b/server/match/server/processor.go index edfd6db..7520cd1 100644 --- a/server/match/server/processor.go +++ b/server/match/server/processor.go @@ -11,6 +11,7 @@ const ( func (s *MatchService) initProcessor() { s.Processor().RegisterMessages(processor.RegisterMetas{ - pb.MsgId_ReqMatchRoomId: {pb.ReqMatchRoom{}, s.onMatchRoom}, + pb.MsgId_ReqMatchRoomId: {pb.ReqMatchRoom{}, s.onMatchRoom}, + pb.MsgId_NtfUserOfflineId: {pb.NtfUserOffline{}, s.onUserOffline}, }) } diff --git a/server/match/server/service.go b/server/match/server/service.go index b5b0b01..47c06f6 100644 --- a/server/match/server/service.go +++ b/server/match/server/service.go @@ -5,6 +5,7 @@ import ( "game/common/gameService" "game/common/proto/pb" "game/common/serviceName" + "game/common/topicName" "game/server/match/config" "game/server/match/match" "github.com/fox/fox/ipb" @@ -56,6 +57,7 @@ func newService(serviceId int) *MatchService { TypeId: int(pb.ServiceTypeId_STI_Match), Version: config.Cfg.BuildDate, }, &config.Cfg.Redis) + _ = s.GameService.Subscribe(topicName.UserOffline) s.initProcessor() s.OnInit()