From f96715acdf217cff259889ca6b19332e86aa9490 Mon Sep 17 00:00:00 2001 From: liuxiaobo <1224730913@qq.com> Date: Tue, 27 May 2025 19:14:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BB=93=E6=9E=84=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E9=99=A4userGate=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/topicName/topicName.go | 2 +- common/userBindService/userService.go | 6 +-- server/gate/model/userGate.go | 77 ++++++++++++--------------- server/gate/model/userGate_test.go | 47 +++++++--------- server/gate/server/processor.go | 21 +++----- server/gate/server/service.go | 17 +++--- 6 files changed, 73 insertions(+), 97 deletions(-) diff --git a/common/topicName/topicName.go b/common/topicName/topicName.go index b9f02e5..c86aaec 100644 --- a/common/topicName/topicName.go +++ b/common/topicName/topicName.go @@ -3,6 +3,6 @@ package topicName const ( //extTopic = ".topic" //extGroup = ".group" - UserLogin = "user.login.topic" + UserOnline = "user.online.topic" UserOffline = "user.offline.topic" ) diff --git a/common/userBindService/userService.go b/common/userBindService/userService.go index 7a1c597..96946ed 100644 --- a/common/userBindService/userService.go +++ b/common/userBindService/userService.go @@ -38,8 +38,8 @@ func (m *UserBindService) makeRedisKey(userId int64, typeId pb.ServiceTypeId) st return fmt.Sprintf("%s_%d:%d", prefix, userId, int(typeId)) } -// 从redis中加载玩家曾经访问过的服务节点 -func (m *UserBindService) loadFromRedis(userId int64, typeId pb.ServiceTypeId) string { +// 从redis中加载玩家曾经访问过的服务节点名 +func (m *UserBindService) LoadFromRedis(userId int64, typeId pb.ServiceTypeId) string { k := m.makeRedisKey(userId, typeId) if sName, err := m.rdb.Get(context.Background(), k).Result(); err != nil { log.Error(err.Error()) @@ -101,7 +101,7 @@ func (m *UserBindService) RandServiceNode(typeId pb.ServiceTypeId) (*etcd.Servic // 根据服务类型,路由到对应的服务节点 func (m *UserBindService) FindServiceName(userId int64, typeId pb.ServiceTypeId) (string, error) { // 内存中没有,向redis中查询。redis中保留的服务节点不一定是可用的,还需要向etcd中验证 - if sName := m.loadFromRedis(userId, typeId); sName != "" && m.serviceIsValid(sName) { + if sName := m.LoadFromRedis(userId, typeId); sName != "" && m.serviceIsValid(sName) { return sName, nil } // redis也没有玩家的服务节点信息,从etcd中找可用服务节点随机选择一个 diff --git a/server/gate/model/userGate.go b/server/gate/model/userGate.go index 69ecdf5..a7fcaaf 100644 --- a/server/gate/model/userGate.go +++ b/server/gate/model/userGate.go @@ -1,45 +1,38 @@ package model -import ( - "context" - "encoding/json" - "fmt" - "game/common/utils" - "github.com/go-redis/redis/v8" - "time" -) +// 该类将玩家与网关绑定以及保存token这些事情混在一起了,绑定关系由userBindService提供。token这些由login服提供 -type UserGate struct { - GateName string `json:"gate_name"` - Token string `json:"token"` - OnlineTime utils.Time `json:"online"` - rdb *redis.Client -} - -func NewUserGate() *UserGate { - return &UserGate{rdb: UserRedis} -} - -func (u *UserGate) key(userId int64, gateId string) string { - return fmt.Sprintf("gateway:%v:%v", gateId, userId) -} - -func (u *UserGate) Set(userId int64, gateId string, token string) { - u.GateName = gateId - u.Token = token - u.OnlineTime = utils.Time(time.Now()) - u.rdb.Set(context.Background(), u.key(userId, gateId), utils.Marshal(u), time.Hour*24) -} - -func (u *UserGate) Get(userId int64, gateId string) (*UserGate, error) { - s, err := u.rdb.Get(context.Background(), u.key(userId, gateId)).Result() - if err != nil { - return u, err - } - err = json.Unmarshal([]byte(s), u) - return u, err -} - -func (u *UserGate) Del(userId int64, gateId string) { - _, _ = u.rdb.Del(context.Background(), u.key(userId, gateId)).Result() -} +//type UserGate struct { +// GateName string `json:"gate_name"` +// Token string `json:"token"` +// OnlineTime utils.Time `json:"online"` +// rdb *redis.Client +//} +// +//func NewUserGate() *UserGate { +// return &UserGate{rdb: UserRedis} +//} +// +//func (u *UserGate) key(userId int64, gateId string) string { +// return fmt.Sprintf("gateway:%v:%v", gateId, userId) +//} +// +//func (u *UserGate) Set(userId int64, gateId string, token string) { +// u.GateName = gateId +// u.Token = token +// u.OnlineTime = utils.Time(time.Now()) +// u.rdb.Set(context.Background(), u.key(userId, gateId), utils.Marshal(u), time.Hour*24) +//} +// +//func (u *UserGate) Get(userId int64, gateId string) (*UserGate, error) { +// s, err := u.rdb.Get(context.Background(), u.key(userId, gateId)).Result() +// if err != nil { +// return u, err +// } +// err = json.Unmarshal([]byte(s), u) +// return u, err +//} +// +//func (u *UserGate) Del(userId int64, gateId string) { +// _, _ = u.rdb.Del(context.Background(), u.key(userId, gateId)).Result() +//} diff --git a/server/gate/model/userGate_test.go b/server/gate/model/userGate_test.go index 46216ea..4a293fe 100644 --- a/server/gate/model/userGate_test.go +++ b/server/gate/model/userGate_test.go @@ -1,29 +1,22 @@ package model -import ( - "game/common/testHelper" - "game/common/utils" - "github.com/fox/fox/db" - "testing" -) - -const ( - userId = 1111 - gateId = "gate-1" - token = "token" -) - -func TestUserGate(t *testing.T) { - UserRedis, err = db.InitRedis(testHelper.RedisPassword, testHelper.Host, testHelper.RedisPort, 0) - if err != nil { - t.Fatal(err) - } - var ug *UserGate - ug, err = NewUserGate().Get(userId, gateId) - if err != nil { - t.Log(err) - ug.Set(userId, gateId, token) - ug, _ = NewUserGate().Get(userId, gateId) - } - t.Logf("user_gate:%v", utils.Marshal(ug)) -} +//const ( +// userId = 1111 +// gateId = "gate-1" +// token = "token" +//) +// +//func TestUserGate(t *testing.T) { +// UserRedis, err = db.InitRedis(testHelper.RedisPassword, testHelper.Host, testHelper.RedisPort, 0) +// if err != nil { +// t.Fatal(err) +// } +// var ug *UserGate +// ug, err = NewUserGate().Get(userId, gateId) +// if err != nil { +// t.Log(err) +// ug.Set(userId, gateId, token) +// ug, _ = NewUserGate().Get(userId, gateId) +// } +// t.Logf("user_gate:%v", utils.Marshal(ug)) +//} diff --git a/server/gate/server/processor.go b/server/gate/server/processor.go index 40910c7..82c7b98 100644 --- a/server/gate/server/processor.go +++ b/server/gate/server/processor.go @@ -2,7 +2,7 @@ package server import ( "game/common/proto/pb" - "game/server/gate/model" + "game/common/topicName" "github.com/fox/fox/processor" "github.com/fox/fox/service" "github.com/fox/fox/ws" @@ -26,25 +26,20 @@ func (s *GateService) onNtfUserOnline(conn ws.IConn, _ *pb.NtfUserOnlineMsg) { // 收到登陆成功消息,判断是否顶号 func (s *GateService) onUserLogin(conn ws.IConn, msg *pb.S2CUserLoginMsg) { - defer func() { - s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogin), msg) - }() // 登陆失败,回传玩家 if msg.Code != pb.ErrCode_EC_OK { + s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogin), msg) return } + s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogin), msg) s.wss.SetUserId(conn.Id(), msg.UserId) - ug, _ := model.NewUserGate().Get(conn.UserId(), s.Name()) - if ug == nil { - model.NewUserGate().Set(conn.UserId(), s.Name(), msg.Token) - return - } + sName := s.bindService.LoadFromRedis(conn.UserId(), pb.ServiceTypeId_STI_Gate) // 网关不同,说明玩家在其它网关上登陆, - if ug.GateName != s.Name() { - s.SendServiceMsg(service.TopicEx(ug.GateName), conn, int32(pb.LoginMsgId_S2CUserLogout), &pb.S2CUserLogoutMsg{Code: pb.ErrCode_EC_LoginDiffLoc}) + if sName != "" && sName != s.Name() { + s.SendServiceMsg(service.TopicEx(sName), conn, int32(pb.LoginMsgId_S2CUserLogout), &pb.S2CUserLogoutMsg{Code: pb.ErrCode_EC_LoginDiffLoc}) } - - //conn.NotifyClose() + // 广播玩家上线 + s.SendServiceMsg(topicName.UserOnline, conn, int32(pb.LoginMsgId_NtfUserOnline), &pb.NtfUserOnlineMsg{UserId: msg.UserId}) } // 收到登出消息 diff --git a/server/gate/server/service.go b/server/gate/server/service.go index 30cd6a7..ea239e0 100644 --- a/server/gate/server/service.go +++ b/server/gate/server/service.go @@ -195,17 +195,12 @@ func (s *GateService) SendClientMsg(conn ws.IConn, msgId int32, msg proto.Messag func (s *GateService) WsOnDisconnect(conn ws.IConn) { if conn.UserId() > 0 { - s.bindService.DelUserService(conn.UserId(), pb.ServiceTypeId_STI_Gate) - ug, err := model.NewUserGate().Get(conn.UserId(), s.Name()) - if err != nil { - log.Error(err.Error()) - } else { - // 相同网关,则为正常下线,删除redis信息然后向内网广播下线 - // 不同网关,异地登陆顶号 由其它网关通知本网关向玩家发送下线消息(processor中处理),并主动关闭连接,不广播下线消息 - if ug.GateName == s.Name() { - model.NewUserGate().Del(conn.UserId(), s.Name()) - s.SendServiceMsg(topicName.UserOffline, conn, int32(pb.LoginMsgId_NtfUserOffline), &pb.NtfUserOfflineMsg{UserId: conn.UserId()}) - } + sName := s.bindService.LoadFromRedis(conn.UserId(), pb.ServiceTypeId_STI_Gate) + // 相同网关,则为正常下线,删除redis信息然后向内网广播下线 + // 不同网关,异地登陆顶号 由其它网关通知本网关向玩家发送顶号消息(processor中处理),并主动关闭连接,不广播下线消息 + if sName == s.Name() { + s.bindService.DelUserService(conn.UserId(), pb.ServiceTypeId_STI_Gate) + s.SendServiceMsg(topicName.UserOffline, conn, int32(pb.LoginMsgId_NtfUserOffline), &pb.NtfUserOfflineMsg{UserId: conn.UserId()}) } log.Debug(s.Log("user:%v disconnect", conn.UserId())) }