优化结构,移除userGate类

This commit is contained in:
liuxiaobo 2025-05-27 19:14:43 +08:00
parent fb7d528825
commit f96715acdf
6 changed files with 73 additions and 97 deletions

View File

@ -3,6 +3,6 @@ package topicName
const ( const (
//extTopic = ".topic" //extTopic = ".topic"
//extGroup = ".group" //extGroup = ".group"
UserLogin = "user.login.topic" UserOnline = "user.online.topic"
UserOffline = "user.offline.topic" UserOffline = "user.offline.topic"
) )

View File

@ -38,8 +38,8 @@ func (m *UserBindService) makeRedisKey(userId int64, typeId pb.ServiceTypeId) st
return fmt.Sprintf("%s_%d:%d", prefix, userId, int(typeId)) return fmt.Sprintf("%s_%d:%d", prefix, userId, int(typeId))
} }
// 从redis中加载玩家曾经访问过的服务节点 // 从redis中加载玩家曾经访问过的服务节点
func (m *UserBindService) loadFromRedis(userId int64, typeId pb.ServiceTypeId) string { func (m *UserBindService) LoadFromRedis(userId int64, typeId pb.ServiceTypeId) string {
k := m.makeRedisKey(userId, typeId) k := m.makeRedisKey(userId, typeId)
if sName, err := m.rdb.Get(context.Background(), k).Result(); err != nil { if sName, err := m.rdb.Get(context.Background(), k).Result(); err != nil {
log.Error(err.Error()) 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) { func (m *UserBindService) FindServiceName(userId int64, typeId pb.ServiceTypeId) (string, error) {
// 内存中没有向redis中查询。redis中保留的服务节点不一定是可用的还需要向etcd中验证 // 内存中没有向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 return sName, nil
} }
// redis也没有玩家的服务节点信息从etcd中找可用服务节点随机选择一个 // redis也没有玩家的服务节点信息从etcd中找可用服务节点随机选择一个

View File

@ -1,45 +1,38 @@
package model package model
import ( // 该类将玩家与网关绑定以及保存token这些事情混在一起了绑定关系由userBindService提供。token这些由login服提供
"context"
"encoding/json"
"fmt"
"game/common/utils"
"github.com/go-redis/redis/v8"
"time"
)
type UserGate struct { //type UserGate struct {
GateName string `json:"gate_name"` // GateName string `json:"gate_name"`
Token string `json:"token"` // Token string `json:"token"`
OnlineTime utils.Time `json:"online"` // OnlineTime utils.Time `json:"online"`
rdb *redis.Client // rdb *redis.Client
} //}
//
func NewUserGate() *UserGate { //func NewUserGate() *UserGate {
return &UserGate{rdb: UserRedis} // return &UserGate{rdb: UserRedis}
} //}
//
func (u *UserGate) key(userId int64, gateId string) string { //func (u *UserGate) key(userId int64, gateId string) string {
return fmt.Sprintf("gateway:%v:%v", gateId, userId) // return fmt.Sprintf("gateway:%v:%v", gateId, userId)
} //}
//
func (u *UserGate) Set(userId int64, gateId string, token string) { //func (u *UserGate) Set(userId int64, gateId string, token string) {
u.GateName = gateId // u.GateName = gateId
u.Token = token // u.Token = token
u.OnlineTime = utils.Time(time.Now()) // u.OnlineTime = utils.Time(time.Now())
u.rdb.Set(context.Background(), u.key(userId, gateId), utils.Marshal(u), time.Hour*24) // 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) { //func (u *UserGate) Get(userId int64, gateId string) (*UserGate, error) {
s, err := u.rdb.Get(context.Background(), u.key(userId, gateId)).Result() // s, err := u.rdb.Get(context.Background(), u.key(userId, gateId)).Result()
if err != nil { // if err != nil {
return u, err // return u, err
} // }
err = json.Unmarshal([]byte(s), u) // err = json.Unmarshal([]byte(s), u)
return u, err // return u, err
} //}
//
func (u *UserGate) Del(userId int64, gateId string) { //func (u *UserGate) Del(userId int64, gateId string) {
_, _ = u.rdb.Del(context.Background(), u.key(userId, gateId)).Result() // _, _ = u.rdb.Del(context.Background(), u.key(userId, gateId)).Result()
} //}

View File

@ -1,29 +1,22 @@
package model package model
import ( //const (
"game/common/testHelper" // userId = 1111
"game/common/utils" // gateId = "gate-1"
"github.com/fox/fox/db" // token = "token"
"testing" //)
) //
//func TestUserGate(t *testing.T) {
const ( // UserRedis, err = db.InitRedis(testHelper.RedisPassword, testHelper.Host, testHelper.RedisPort, 0)
userId = 1111 // if err != nil {
gateId = "gate-1" // t.Fatal(err)
token = "token" // }
) // var ug *UserGate
// ug, err = NewUserGate().Get(userId, gateId)
func TestUserGate(t *testing.T) { // if err != nil {
UserRedis, err = db.InitRedis(testHelper.RedisPassword, testHelper.Host, testHelper.RedisPort, 0) // t.Log(err)
if err != nil { // ug.Set(userId, gateId, token)
t.Fatal(err) // ug, _ = NewUserGate().Get(userId, gateId)
} // }
var ug *UserGate // t.Logf("user_gate:%v", utils.Marshal(ug))
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))
}

View File

@ -2,7 +2,7 @@ package server
import ( import (
"game/common/proto/pb" "game/common/proto/pb"
"game/server/gate/model" "game/common/topicName"
"github.com/fox/fox/processor" "github.com/fox/fox/processor"
"github.com/fox/fox/service" "github.com/fox/fox/service"
"github.com/fox/fox/ws" "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) { 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 { if msg.Code != pb.ErrCode_EC_OK {
s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogin), msg)
return return
} }
s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogin), msg)
s.wss.SetUserId(conn.Id(), msg.UserId) s.wss.SetUserId(conn.Id(), msg.UserId)
ug, _ := model.NewUserGate().Get(conn.UserId(), s.Name()) sName := s.bindService.LoadFromRedis(conn.UserId(), pb.ServiceTypeId_STI_Gate)
if ug == nil {
model.NewUserGate().Set(conn.UserId(), s.Name(), msg.Token)
return
}
// 网关不同,说明玩家在其它网关上登陆, // 网关不同,说明玩家在其它网关上登陆,
if ug.GateName != s.Name() { if sName != "" && sName != s.Name() {
s.SendServiceMsg(service.TopicEx(ug.GateName), conn, int32(pb.LoginMsgId_S2CUserLogout), &pb.S2CUserLogoutMsg{Code: pb.ErrCode_EC_LoginDiffLoc}) 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})
} }
// 收到登出消息 // 收到登出消息

View File

@ -195,18 +195,13 @@ func (s *GateService) SendClientMsg(conn ws.IConn, msgId int32, msg proto.Messag
func (s *GateService) WsOnDisconnect(conn ws.IConn) { func (s *GateService) WsOnDisconnect(conn ws.IConn) {
if conn.UserId() > 0 { if conn.UserId() > 0 {
s.bindService.DelUserService(conn.UserId(), pb.ServiceTypeId_STI_Gate) sName := s.bindService.LoadFromRedis(conn.UserId(), pb.ServiceTypeId_STI_Gate)
ug, err := model.NewUserGate().Get(conn.UserId(), s.Name())
if err != nil {
log.Error(err.Error())
} else {
// 相同网关则为正常下线删除redis信息然后向内网广播下线 // 相同网关则为正常下线删除redis信息然后向内网广播下线
// 不同网关,异地登陆顶号 由其它网关通知本网关向玩家发送下线消息(processor中处理),并主动关闭连接,不广播下线消息 // 不同网关,异地登陆顶号 由其它网关通知本网关向玩家发送顶号消息(processor中处理),并主动关闭连接,不广播下线消息
if ug.GateName == s.Name() { if sName == s.Name() {
model.NewUserGate().Del(conn.UserId(), 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()}) s.SendServiceMsg(topicName.UserOffline, conn, int32(pb.LoginMsgId_NtfUserOffline), &pb.NtfUserOfflineMsg{UserId: conn.UserId()})
} }
}
log.Debug(s.Log("user:%v disconnect", conn.UserId())) log.Debug(s.Log("user:%v disconnect", conn.UserId()))
} }
} }