网关路由消息规则,还需要完善
This commit is contained in:
parent
491e45d7cf
commit
0676c23c28
@ -4,6 +4,7 @@ type Common[T any] struct {
|
||||
ServiceType int `json:"service_type"`
|
||||
Logger Logger `json:"logger"`
|
||||
Etcd Etcd `json:"etcd"`
|
||||
Redis Redis `json:"redis"`
|
||||
Nats Nats `json:"nats"`
|
||||
Special *T `json:"special"`
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"game/common/testHelper"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
@ -16,6 +17,10 @@ const (
|
||||
etcdAddress = "114.132.124.145:2379"
|
||||
natsKey = "nats_config"
|
||||
natsAddress = "nats://114.132.124.145:4222"
|
||||
redisKey = "redis_config"
|
||||
redisAddress = testHelper.Host
|
||||
redisPort = testHelper.RedisPort
|
||||
redisPassword = testHelper.RedisPassword
|
||||
)
|
||||
|
||||
func LoadSpecialConfig[T any](rd *redis.Client, specialKey string, comm *Common[T]) error {
|
||||
@ -43,6 +48,7 @@ func LoadCommonConfig[T any](rd *redis.Client) (*Common[T], error) {
|
||||
var ret resultT[T]
|
||||
var comm Common[T]
|
||||
comm.Special = &ret.Value
|
||||
// 初始化etcd
|
||||
s, err := rd.Get(context.Background(), etcdKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
log.FatalF("init config:%v", err)
|
||||
@ -61,6 +67,8 @@ func LoadCommonConfig[T any](rd *redis.Client) (*Common[T], error) {
|
||||
} else {
|
||||
err = json.Unmarshal([]byte(s), &comm.Etcd)
|
||||
}
|
||||
|
||||
// 初始化nats
|
||||
s, err = rd.Get(context.Background(), natsKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
log.FatalF("init config:%v", err)
|
||||
@ -75,6 +83,22 @@ func LoadCommonConfig[T any](rd *redis.Client) (*Common[T], error) {
|
||||
} else {
|
||||
err = json.Unmarshal([]byte(s), &comm.Nats)
|
||||
}
|
||||
|
||||
// 初始化redis
|
||||
s, err = rd.Get(context.Background(), redisKey).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
log.FatalF("init config:%v", err)
|
||||
return nil, err
|
||||
}
|
||||
if s == "" {
|
||||
log.DebugF("load config:empty redis key")
|
||||
comm.Redis = Redis{Host: redisAddress, Port: redisPort, Password: redisPassword}
|
||||
if bs, err := json.Marshal(&comm.Redis); err == nil {
|
||||
err = rd.Set(context.Background(), redisKey, string(bs), 0).Err()
|
||||
}
|
||||
} else {
|
||||
err = json.Unmarshal([]byte(s), &comm.Redis)
|
||||
}
|
||||
return &comm, nil
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,20 @@
|
||||
syntax = "proto3";
|
||||
package internal;
|
||||
option go_package = "common/proto/internal";
|
||||
package ipb;
|
||||
option go_package = "common/proto/ipb";
|
||||
|
||||
enum MsgId
|
||||
{
|
||||
Unknown = 0;
|
||||
Internal = -1; // 玩家申请进入房间
|
||||
Internal = -1; // 内部消息id
|
||||
}
|
||||
|
||||
|
||||
message InternalMsg
|
||||
{
|
||||
int64 user_id = 1; // 玩家id
|
||||
int32 msg_id = 2; // 消息id
|
||||
bytes msg = 3; // 消息
|
||||
uint32 conn_id = 1; // 刚登陆时没有user_id,只有conn_id
|
||||
int64 user_id = 2; // 玩家id
|
||||
int32 msg_id = 3; // 消息id
|
||||
bytes msg = 4; // 消息
|
||||
}
|
||||
|
||||
// 网关解包客户端消息
|
||||
|
15
common/pb/client.proto
Normal file
15
common/pb/client.proto
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
import "service.proto";
|
||||
|
||||
|
||||
message ClientMsg
|
||||
{
|
||||
ServiceTypeId service_id = 1; // 服务id
|
||||
int32 msg_id = 2; // 消息id
|
||||
bytes data = 3; // 消息体
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
syntax = "proto3";
|
||||
package internal;
|
||||
option go_package = "common/proto";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
enum ErrCode
|
||||
{
|
||||
OK = 0;
|
||||
LoginFail = 1; // 登陆失败
|
||||
EC_OK = 0;
|
||||
EC_LoginDiffLoc = 1; // 帐号在其它地方登陆
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,27 +1,55 @@
|
||||
syntax = "proto3";
|
||||
package internal;
|
||||
option go_package = "common/proto";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
import "code.proto";
|
||||
|
||||
enum LoginMsgId
|
||||
{
|
||||
Unknown = 0;
|
||||
C2SLogin = 1; // 玩家登陆
|
||||
C2SUserLogin = 1; // 玩家登陆
|
||||
S2SUserLogin = 2;
|
||||
NtfUserOnline = 3;
|
||||
C2SUserLogout = 4;
|
||||
S2CUserLogout = 5;
|
||||
NtfUserOffline = 6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 玩家登陆
|
||||
message C2SLoginMsg
|
||||
message C2SUserLoginMsg
|
||||
{
|
||||
string username = 1; // 用户名
|
||||
string token = 2; // 密码或token
|
||||
string version = 3; // 版本
|
||||
}
|
||||
|
||||
message S2CLoginMsg
|
||||
message S2CUserLoginMsg
|
||||
{
|
||||
ErrCode code = 1;
|
||||
int64 user_id = 2;
|
||||
}
|
||||
|
||||
// 上线通知
|
||||
message NtfUserOnlineMsg
|
||||
{
|
||||
int64 user_id = 2; // 玩家id
|
||||
}
|
||||
|
||||
// 玩家登陆
|
||||
message C2SUserLogoutMsg
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
message S2CUserLogoutMsg
|
||||
{
|
||||
ErrCode code = 1; // 登出原因
|
||||
}
|
||||
|
||||
// 下线通知
|
||||
message NtfUserOfflineMsg
|
||||
{
|
||||
int64 user_id = 2; // 玩家id
|
||||
}
|
12
common/pb/service.proto
Normal file
12
common/pb/service.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
package pb;
|
||||
option go_package = "common/proto/pb";
|
||||
|
||||
enum ServiceTypeId
|
||||
{
|
||||
STI_Unknown = 0;
|
||||
STI_Gate = 1000; // 网关id
|
||||
STI_Login = 1001; // 登陆服
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// protoc v6.31.0
|
||||
// source: internal.proto
|
||||
|
||||
package internal
|
||||
package ipb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
@ -25,7 +25,7 @@ type MsgId int32
|
||||
|
||||
const (
|
||||
MsgId_Unknown MsgId = 0
|
||||
MsgId_Internal MsgId = -1 // 玩家申请进入房间
|
||||
MsgId_Internal MsgId = -1 // 内部消息id
|
||||
)
|
||||
|
||||
// Enum value maps for MsgId.
|
||||
@ -69,9 +69,10 @@ func (MsgId) EnumDescriptor() ([]byte, []int) {
|
||||
|
||||
type InternalMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 玩家id
|
||||
MsgId int32 `protobuf:"varint,2,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"` // 消息id
|
||||
Msg []byte `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` // 消息
|
||||
ConnId uint32 `protobuf:"varint,1,opt,name=conn_id,json=connId,proto3" json:"conn_id,omitempty"` // 刚登陆时没有user_id,只有conn_id
|
||||
UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 玩家id
|
||||
MsgId int32 `protobuf:"varint,3,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"` // 消息id
|
||||
Msg []byte `protobuf:"bytes,4,opt,name=msg,proto3" json:"msg,omitempty"` // 消息
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@ -106,6 +107,13 @@ func (*InternalMsg) Descriptor() ([]byte, []int) {
|
||||
return file_internal_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *InternalMsg) GetConnId() uint32 {
|
||||
if x != nil {
|
||||
return x.ConnId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *InternalMsg) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
@ -200,11 +208,12 @@ var File_internal_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_internal_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x0einternal.proto\x12\binternal\"O\n" +
|
||||
"\x0einternal.proto\x12\x03ipb\"h\n" +
|
||||
"\vInternalMsg\x12\x17\n" +
|
||||
"\auser_id\x18\x01 \x01(\x03R\x06userId\x12\x15\n" +
|
||||
"\x06msg_id\x18\x02 \x01(\x05R\x05msgId\x12\x10\n" +
|
||||
"\x03msg\x18\x03 \x01(\fR\x03msg\"q\n" +
|
||||
"\aconn_id\x18\x01 \x01(\rR\x06connId\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\x03R\x06userId\x12\x15\n" +
|
||||
"\x06msg_id\x18\x03 \x01(\x05R\x05msgId\x12\x10\n" +
|
||||
"\x03msg\x18\x04 \x01(\fR\x03msg\"q\n" +
|
||||
"\n" +
|
||||
"C2SMessage\x12!\n" +
|
||||
"\fservice_type\x18\x01 \x01(\x05R\vserviceType\x12\x15\n" +
|
||||
@ -213,7 +222,7 @@ const file_internal_proto_rawDesc = "" +
|
||||
"\x03msg\x18\x04 \x01(\fR\x03msg*+\n" +
|
||||
"\x05MsgId\x12\v\n" +
|
||||
"\aUnknown\x10\x00\x12\x15\n" +
|
||||
"\bInternal\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01B\x17Z\x15common/proto/internalb\x06proto3"
|
||||
"\bInternal\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01B\x12Z\x10common/proto/ipbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_internal_proto_rawDescOnce sync.Once
|
||||
@ -230,9 +239,9 @@ func file_internal_proto_rawDescGZIP() []byte {
|
||||
var file_internal_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_internal_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_internal_proto_goTypes = []any{
|
||||
(MsgId)(0), // 0: internal.MsgId
|
||||
(*InternalMsg)(nil), // 1: internal.InternalMsg
|
||||
(*C2SMessage)(nil), // 2: internal.C2SMessage
|
||||
(MsgId)(0), // 0: ipb.MsgId
|
||||
(*InternalMsg)(nil), // 1: ipb.InternalMsg
|
||||
(*C2SMessage)(nil), // 2: ipb.C2SMessage
|
||||
}
|
||||
var file_internal_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
@ -1,245 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: login.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type LoginMsgId int32
|
||||
|
||||
const (
|
||||
LoginMsgId_Unknown LoginMsgId = 0
|
||||
LoginMsgId_C2SLogin LoginMsgId = 1 // 玩家登陆
|
||||
)
|
||||
|
||||
// Enum value maps for LoginMsgId.
|
||||
var (
|
||||
LoginMsgId_name = map[int32]string{
|
||||
0: "Unknown",
|
||||
1: "C2SLogin",
|
||||
}
|
||||
LoginMsgId_value = map[string]int32{
|
||||
"Unknown": 0,
|
||||
"C2SLogin": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x LoginMsgId) Enum() *LoginMsgId {
|
||||
p := new(LoginMsgId)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x LoginMsgId) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (LoginMsgId) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_login_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (LoginMsgId) Type() protoreflect.EnumType {
|
||||
return &file_login_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x LoginMsgId) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use LoginMsgId.Descriptor instead.
|
||||
func (LoginMsgId) EnumDescriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// 玩家登陆
|
||||
type C2SLoginMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` // 用户名
|
||||
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` // 密码或token
|
||||
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // 版本
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *C2SLoginMsg) Reset() {
|
||||
*x = C2SLoginMsg{}
|
||||
mi := &file_login_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *C2SLoginMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*C2SLoginMsg) ProtoMessage() {}
|
||||
|
||||
func (x *C2SLoginMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use C2SLoginMsg.ProtoReflect.Descriptor instead.
|
||||
func (*C2SLoginMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *C2SLoginMsg) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *C2SLoginMsg) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *C2SLoginMsg) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type S2CLoginMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code ErrCode `protobuf:"varint,1,opt,name=code,proto3,enum=internal.ErrCode" json:"code,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *S2CLoginMsg) Reset() {
|
||||
*x = S2CLoginMsg{}
|
||||
mi := &file_login_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *S2CLoginMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2CLoginMsg) ProtoMessage() {}
|
||||
|
||||
func (x *S2CLoginMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2CLoginMsg.ProtoReflect.Descriptor instead.
|
||||
func (*S2CLoginMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *S2CLoginMsg) GetCode() ErrCode {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return ErrCode_OK
|
||||
}
|
||||
|
||||
var File_login_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_login_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vlogin.proto\x12\binternal\x1a\n" +
|
||||
"code.proto\"Y\n" +
|
||||
"\vC2SLoginMsg\x12\x1a\n" +
|
||||
"\busername\x18\x01 \x01(\tR\busername\x12\x14\n" +
|
||||
"\x05token\x18\x02 \x01(\tR\x05token\x12\x18\n" +
|
||||
"\aversion\x18\x03 \x01(\tR\aversion\"4\n" +
|
||||
"\vS2CLoginMsg\x12%\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2\x11.internal.ErrCodeR\x04code*'\n" +
|
||||
"\n" +
|
||||
"LoginMsgId\x12\v\n" +
|
||||
"\aUnknown\x10\x00\x12\f\n" +
|
||||
"\bC2SLogin\x10\x01B\x0eZ\fcommon/protob\x06proto3"
|
||||
|
||||
var (
|
||||
file_login_proto_rawDescOnce sync.Once
|
||||
file_login_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_login_proto_rawDescGZIP() []byte {
|
||||
file_login_proto_rawDescOnce.Do(func() {
|
||||
file_login_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_login_proto_rawDesc), len(file_login_proto_rawDesc)))
|
||||
})
|
||||
return file_login_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_login_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_login_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_login_proto_goTypes = []any{
|
||||
(LoginMsgId)(0), // 0: internal.LoginMsgId
|
||||
(*C2SLoginMsg)(nil), // 1: internal.C2SLoginMsg
|
||||
(*S2CLoginMsg)(nil), // 2: internal.S2CLoginMsg
|
||||
(ErrCode)(0), // 3: internal.ErrCode
|
||||
}
|
||||
var file_login_proto_depIdxs = []int32{
|
||||
3, // 0: internal.S2CLoginMsg.code:type_name -> internal.ErrCode
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_login_proto_init() }
|
||||
func file_login_proto_init() {
|
||||
if File_login_proto != nil {
|
||||
return
|
||||
}
|
||||
file_code_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_login_proto_rawDesc), len(file_login_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_login_proto_goTypes,
|
||||
DependencyIndexes: file_login_proto_depIdxs,
|
||||
EnumInfos: file_login_proto_enumTypes,
|
||||
MessageInfos: file_login_proto_msgTypes,
|
||||
}.Build()
|
||||
File_login_proto = out.File
|
||||
file_login_proto_goTypes = nil
|
||||
file_login_proto_depIdxs = nil
|
||||
}
|
144
common/proto/pb/client.pb.go
Normal file
144
common/proto/pb/client.pb.go
Normal file
@ -0,0 +1,144 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: client.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ClientMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
ServiceId ServiceTypeId `protobuf:"varint,1,opt,name=service_id,json=serviceId,proto3,enum=pb.ServiceTypeId" json:"service_id,omitempty"` // 服务id
|
||||
MsgId int32 `protobuf:"varint,2,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"` // 消息id
|
||||
Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // 消息体
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ClientMsg) Reset() {
|
||||
*x = ClientMsg{}
|
||||
mi := &file_client_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ClientMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ClientMsg) ProtoMessage() {}
|
||||
|
||||
func (x *ClientMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_client_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ClientMsg.ProtoReflect.Descriptor instead.
|
||||
func (*ClientMsg) Descriptor() ([]byte, []int) {
|
||||
return file_client_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ClientMsg) GetServiceId() ServiceTypeId {
|
||||
if x != nil {
|
||||
return x.ServiceId
|
||||
}
|
||||
return ServiceTypeId_STI_Unknown
|
||||
}
|
||||
|
||||
func (x *ClientMsg) GetMsgId() int32 {
|
||||
if x != nil {
|
||||
return x.MsgId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ClientMsg) GetData() []byte {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_client_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_client_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\fclient.proto\x12\x02pb\x1a\rservice.proto\"h\n" +
|
||||
"\tClientMsg\x120\n" +
|
||||
"\n" +
|
||||
"service_id\x18\x01 \x01(\x0e2\x11.pb.ServiceTypeIdR\tserviceId\x12\x15\n" +
|
||||
"\x06msg_id\x18\x02 \x01(\x05R\x05msgId\x12\x12\n" +
|
||||
"\x04data\x18\x03 \x01(\fR\x04dataB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_client_proto_rawDescOnce sync.Once
|
||||
file_client_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_client_proto_rawDescGZIP() []byte {
|
||||
file_client_proto_rawDescOnce.Do(func() {
|
||||
file_client_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_client_proto_rawDesc), len(file_client_proto_rawDesc)))
|
||||
})
|
||||
return file_client_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_client_proto_goTypes = []any{
|
||||
(*ClientMsg)(nil), // 0: pb.ClientMsg
|
||||
(ServiceTypeId)(0), // 1: pb.ServiceTypeId
|
||||
}
|
||||
var file_client_proto_depIdxs = []int32{
|
||||
1, // 0: pb.ClientMsg.service_id:type_name -> pb.ServiceTypeId
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_client_proto_init() }
|
||||
func file_client_proto_init() {
|
||||
if File_client_proto != nil {
|
||||
return
|
||||
}
|
||||
file_service_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_client_proto_rawDesc), len(file_client_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_client_proto_goTypes,
|
||||
DependencyIndexes: file_client_proto_depIdxs,
|
||||
MessageInfos: file_client_proto_msgTypes,
|
||||
}.Build()
|
||||
File_client_proto = out.File
|
||||
file_client_proto_goTypes = nil
|
||||
file_client_proto_depIdxs = nil
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
// protoc v6.31.0
|
||||
// source: code.proto
|
||||
|
||||
package proto
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
@ -24,19 +24,19 @@ const (
|
||||
type ErrCode int32
|
||||
|
||||
const (
|
||||
ErrCode_OK ErrCode = 0
|
||||
ErrCode_LoginFail ErrCode = 1 // 登陆失败
|
||||
ErrCode_EC_OK ErrCode = 0
|
||||
ErrCode_EC_LoginDiffLoc ErrCode = 1 // 帐号在其它地方登陆
|
||||
)
|
||||
|
||||
// Enum value maps for ErrCode.
|
||||
var (
|
||||
ErrCode_name = map[int32]string{
|
||||
0: "OK",
|
||||
1: "LoginFail",
|
||||
0: "EC_OK",
|
||||
1: "EC_LoginDiffLoc",
|
||||
}
|
||||
ErrCode_value = map[string]int32{
|
||||
"OK": 0,
|
||||
"LoginFail": 1,
|
||||
"EC_OK": 0,
|
||||
"EC_LoginDiffLoc": 1,
|
||||
}
|
||||
)
|
||||
|
||||
@ -72,10 +72,10 @@ var File_code_proto protoreflect.FileDescriptor
|
||||
const file_code_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"code.proto\x12\binternal* \n" +
|
||||
"\aErrCode\x12\x06\n" +
|
||||
"\x02OK\x10\x00\x12\r\n" +
|
||||
"\tLoginFail\x10\x01B\x0eZ\fcommon/protob\x06proto3"
|
||||
"code.proto\x12\x02pb*)\n" +
|
||||
"\aErrCode\x12\t\n" +
|
||||
"\x05EC_OK\x10\x00\x12\x13\n" +
|
||||
"\x0fEC_LoginDiffLoc\x10\x01B\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_code_proto_rawDescOnce sync.Once
|
||||
@ -91,7 +91,7 @@ func file_code_proto_rawDescGZIP() []byte {
|
||||
|
||||
var file_code_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_code_proto_goTypes = []any{
|
||||
(ErrCode)(0), // 0: internal.ErrCode
|
||||
(ErrCode)(0), // 0: pb.ErrCode
|
||||
}
|
||||
var file_code_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
457
common/proto/pb/login.pb.go
Normal file
457
common/proto/pb/login.pb.go
Normal file
@ -0,0 +1,457 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: login.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type LoginMsgId int32
|
||||
|
||||
const (
|
||||
LoginMsgId_Unknown LoginMsgId = 0
|
||||
LoginMsgId_C2SUserLogin LoginMsgId = 1 // 玩家登陆
|
||||
LoginMsgId_S2SUserLogin LoginMsgId = 2
|
||||
LoginMsgId_NtfUserOnline LoginMsgId = 3
|
||||
LoginMsgId_C2SUserLogout LoginMsgId = 4
|
||||
LoginMsgId_S2CUserLogout LoginMsgId = 5
|
||||
LoginMsgId_NtfUserOffline LoginMsgId = 6
|
||||
)
|
||||
|
||||
// Enum value maps for LoginMsgId.
|
||||
var (
|
||||
LoginMsgId_name = map[int32]string{
|
||||
0: "Unknown",
|
||||
1: "C2SUserLogin",
|
||||
2: "S2SUserLogin",
|
||||
3: "NtfUserOnline",
|
||||
4: "C2SUserLogout",
|
||||
5: "S2CUserLogout",
|
||||
6: "NtfUserOffline",
|
||||
}
|
||||
LoginMsgId_value = map[string]int32{
|
||||
"Unknown": 0,
|
||||
"C2SUserLogin": 1,
|
||||
"S2SUserLogin": 2,
|
||||
"NtfUserOnline": 3,
|
||||
"C2SUserLogout": 4,
|
||||
"S2CUserLogout": 5,
|
||||
"NtfUserOffline": 6,
|
||||
}
|
||||
)
|
||||
|
||||
func (x LoginMsgId) Enum() *LoginMsgId {
|
||||
p := new(LoginMsgId)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x LoginMsgId) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (LoginMsgId) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_login_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (LoginMsgId) Type() protoreflect.EnumType {
|
||||
return &file_login_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x LoginMsgId) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use LoginMsgId.Descriptor instead.
|
||||
func (LoginMsgId) EnumDescriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// 玩家登陆
|
||||
type C2SUserLoginMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` // 用户名
|
||||
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` // 密码或token
|
||||
Version string `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` // 版本
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *C2SUserLoginMsg) Reset() {
|
||||
*x = C2SUserLoginMsg{}
|
||||
mi := &file_login_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *C2SUserLoginMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*C2SUserLoginMsg) ProtoMessage() {}
|
||||
|
||||
func (x *C2SUserLoginMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use C2SUserLoginMsg.ProtoReflect.Descriptor instead.
|
||||
func (*C2SUserLoginMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *C2SUserLoginMsg) GetUsername() string {
|
||||
if x != nil {
|
||||
return x.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *C2SUserLoginMsg) GetToken() string {
|
||||
if x != nil {
|
||||
return x.Token
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *C2SUserLoginMsg) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type S2CUserLoginMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code ErrCode `protobuf:"varint,1,opt,name=code,proto3,enum=pb.ErrCode" json:"code,omitempty"`
|
||||
UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *S2CUserLoginMsg) Reset() {
|
||||
*x = S2CUserLoginMsg{}
|
||||
mi := &file_login_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *S2CUserLoginMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2CUserLoginMsg) ProtoMessage() {}
|
||||
|
||||
func (x *S2CUserLoginMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2CUserLoginMsg.ProtoReflect.Descriptor instead.
|
||||
func (*S2CUserLoginMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *S2CUserLoginMsg) GetCode() ErrCode {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return ErrCode_EC_OK
|
||||
}
|
||||
|
||||
func (x *S2CUserLoginMsg) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 上线通知
|
||||
type NtfUserOnlineMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 玩家id
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NtfUserOnlineMsg) Reset() {
|
||||
*x = NtfUserOnlineMsg{}
|
||||
mi := &file_login_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *NtfUserOnlineMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NtfUserOnlineMsg) ProtoMessage() {}
|
||||
|
||||
func (x *NtfUserOnlineMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NtfUserOnlineMsg.ProtoReflect.Descriptor instead.
|
||||
func (*NtfUserOnlineMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *NtfUserOnlineMsg) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 玩家登陆
|
||||
type C2SUserLogoutMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *C2SUserLogoutMsg) Reset() {
|
||||
*x = C2SUserLogoutMsg{}
|
||||
mi := &file_login_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *C2SUserLogoutMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*C2SUserLogoutMsg) ProtoMessage() {}
|
||||
|
||||
func (x *C2SUserLogoutMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use C2SUserLogoutMsg.ProtoReflect.Descriptor instead.
|
||||
func (*C2SUserLogoutMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type S2CUserLogoutMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code ErrCode `protobuf:"varint,1,opt,name=code,proto3,enum=pb.ErrCode" json:"code,omitempty"` // 登出原因
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *S2CUserLogoutMsg) Reset() {
|
||||
*x = S2CUserLogoutMsg{}
|
||||
mi := &file_login_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *S2CUserLogoutMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*S2CUserLogoutMsg) ProtoMessage() {}
|
||||
|
||||
func (x *S2CUserLogoutMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use S2CUserLogoutMsg.ProtoReflect.Descriptor instead.
|
||||
func (*S2CUserLogoutMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *S2CUserLogoutMsg) GetCode() ErrCode {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return ErrCode_EC_OK
|
||||
}
|
||||
|
||||
// 下线通知
|
||||
type NtfUserOfflineMsg struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
UserId int64 `protobuf:"varint,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` // 玩家id
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NtfUserOfflineMsg) Reset() {
|
||||
*x = NtfUserOfflineMsg{}
|
||||
mi := &file_login_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *NtfUserOfflineMsg) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NtfUserOfflineMsg) ProtoMessage() {}
|
||||
|
||||
func (x *NtfUserOfflineMsg) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_login_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NtfUserOfflineMsg.ProtoReflect.Descriptor instead.
|
||||
func (*NtfUserOfflineMsg) Descriptor() ([]byte, []int) {
|
||||
return file_login_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
func (x *NtfUserOfflineMsg) GetUserId() int64 {
|
||||
if x != nil {
|
||||
return x.UserId
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_login_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_login_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vlogin.proto\x12\x02pb\x1a\n" +
|
||||
"code.proto\"]\n" +
|
||||
"\x0fC2SUserLoginMsg\x12\x1a\n" +
|
||||
"\busername\x18\x01 \x01(\tR\busername\x12\x14\n" +
|
||||
"\x05token\x18\x02 \x01(\tR\x05token\x12\x18\n" +
|
||||
"\aversion\x18\x03 \x01(\tR\aversion\"K\n" +
|
||||
"\x0fS2CUserLoginMsg\x12\x1f\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2\v.pb.ErrCodeR\x04code\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\x03R\x06userId\"+\n" +
|
||||
"\x10NtfUserOnlineMsg\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\x03R\x06userId\"\x12\n" +
|
||||
"\x10C2SUserLogoutMsg\"3\n" +
|
||||
"\x10S2CUserLogoutMsg\x12\x1f\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2\v.pb.ErrCodeR\x04code\",\n" +
|
||||
"\x11NtfUserOfflineMsg\x12\x17\n" +
|
||||
"\auser_id\x18\x02 \x01(\x03R\x06userId*\x8a\x01\n" +
|
||||
"\n" +
|
||||
"LoginMsgId\x12\v\n" +
|
||||
"\aUnknown\x10\x00\x12\x10\n" +
|
||||
"\fC2SUserLogin\x10\x01\x12\x10\n" +
|
||||
"\fS2SUserLogin\x10\x02\x12\x11\n" +
|
||||
"\rNtfUserOnline\x10\x03\x12\x11\n" +
|
||||
"\rC2SUserLogout\x10\x04\x12\x11\n" +
|
||||
"\rS2CUserLogout\x10\x05\x12\x12\n" +
|
||||
"\x0eNtfUserOffline\x10\x06B\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_login_proto_rawDescOnce sync.Once
|
||||
file_login_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_login_proto_rawDescGZIP() []byte {
|
||||
file_login_proto_rawDescOnce.Do(func() {
|
||||
file_login_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_login_proto_rawDesc), len(file_login_proto_rawDesc)))
|
||||
})
|
||||
return file_login_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_login_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_login_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||
var file_login_proto_goTypes = []any{
|
||||
(LoginMsgId)(0), // 0: pb.LoginMsgId
|
||||
(*C2SUserLoginMsg)(nil), // 1: pb.C2SUserLoginMsg
|
||||
(*S2CUserLoginMsg)(nil), // 2: pb.S2CUserLoginMsg
|
||||
(*NtfUserOnlineMsg)(nil), // 3: pb.NtfUserOnlineMsg
|
||||
(*C2SUserLogoutMsg)(nil), // 4: pb.C2SUserLogoutMsg
|
||||
(*S2CUserLogoutMsg)(nil), // 5: pb.S2CUserLogoutMsg
|
||||
(*NtfUserOfflineMsg)(nil), // 6: pb.NtfUserOfflineMsg
|
||||
(ErrCode)(0), // 7: pb.ErrCode
|
||||
}
|
||||
var file_login_proto_depIdxs = []int32{
|
||||
7, // 0: pb.S2CUserLoginMsg.code:type_name -> pb.ErrCode
|
||||
7, // 1: pb.S2CUserLogoutMsg.code:type_name -> pb.ErrCode
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_login_proto_init() }
|
||||
func file_login_proto_init() {
|
||||
if File_login_proto != nil {
|
||||
return
|
||||
}
|
||||
file_code_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_login_proto_rawDesc), len(file_login_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 6,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_login_proto_goTypes,
|
||||
DependencyIndexes: file_login_proto_depIdxs,
|
||||
EnumInfos: file_login_proto_enumTypes,
|
||||
MessageInfos: file_login_proto_msgTypes,
|
||||
}.Build()
|
||||
File_login_proto = out.File
|
||||
file_login_proto_goTypes = nil
|
||||
file_login_proto_depIdxs = nil
|
||||
}
|
129
common/proto/pb/service.pb.go
Normal file
129
common/proto/pb/service.pb.go
Normal file
@ -0,0 +1,129 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.31.0
|
||||
// source: service.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ServiceTypeId int32
|
||||
|
||||
const (
|
||||
ServiceTypeId_STI_Unknown ServiceTypeId = 0
|
||||
ServiceTypeId_STI_Gate ServiceTypeId = 1000 // 网关id
|
||||
ServiceTypeId_STI_Login ServiceTypeId = 1001 // 登陆服
|
||||
)
|
||||
|
||||
// Enum value maps for ServiceTypeId.
|
||||
var (
|
||||
ServiceTypeId_name = map[int32]string{
|
||||
0: "STI_Unknown",
|
||||
1000: "STI_Gate",
|
||||
1001: "STI_Login",
|
||||
}
|
||||
ServiceTypeId_value = map[string]int32{
|
||||
"STI_Unknown": 0,
|
||||
"STI_Gate": 1000,
|
||||
"STI_Login": 1001,
|
||||
}
|
||||
)
|
||||
|
||||
func (x ServiceTypeId) Enum() *ServiceTypeId {
|
||||
p := new(ServiceTypeId)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x ServiceTypeId) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (ServiceTypeId) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_service_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (ServiceTypeId) Type() protoreflect.EnumType {
|
||||
return &file_service_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x ServiceTypeId) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ServiceTypeId.Descriptor instead.
|
||||
func (ServiceTypeId) EnumDescriptor() ([]byte, []int) {
|
||||
return file_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var File_service_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_service_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\rservice.proto\x12\x02pb*?\n" +
|
||||
"\rServiceTypeId\x12\x0f\n" +
|
||||
"\vSTI_Unknown\x10\x00\x12\r\n" +
|
||||
"\bSTI_Gate\x10\xe8\a\x12\x0e\n" +
|
||||
"\tSTI_Login\x10\xe9\aB\x11Z\x0fcommon/proto/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_service_proto_rawDescOnce sync.Once
|
||||
file_service_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_service_proto_rawDescGZIP() []byte {
|
||||
file_service_proto_rawDescOnce.Do(func() {
|
||||
file_service_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_service_proto_rawDesc), len(file_service_proto_rawDesc)))
|
||||
})
|
||||
return file_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_service_proto_goTypes = []any{
|
||||
(ServiceTypeId)(0), // 0: pb.ServiceTypeId
|
||||
}
|
||||
var file_service_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_service_proto_init() }
|
||||
func file_service_proto_init() {
|
||||
if File_service_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_service_proto_rawDesc), len(file_service_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_service_proto_goTypes,
|
||||
DependencyIndexes: file_service_proto_depIdxs,
|
||||
EnumInfos: file_service_proto_enumTypes,
|
||||
}.Build()
|
||||
File_service_proto = out.File
|
||||
file_service_proto_goTypes = nil
|
||||
file_service_proto_depIdxs = nil
|
||||
}
|
7
common/testHelper/testHelper.go
Normal file
7
common/testHelper/testHelper.go
Normal file
@ -0,0 +1,7 @@
|
||||
package testHelper
|
||||
|
||||
const (
|
||||
Host = "114.132.124.145"
|
||||
RedisPort = "6379"
|
||||
RedisPassword = "fox379@@zyxi"
|
||||
)
|
@ -1,6 +1,8 @@
|
||||
package topicName
|
||||
|
||||
const (
|
||||
UserLogin = "user.login"
|
||||
UserOffline = "user.offline"
|
||||
//extTopic = ".topic"
|
||||
//extGroup = ".group"
|
||||
UserLogin = "user.login.topic"
|
||||
UserOffline = "user.offline.topic"
|
||||
)
|
||||
|
29
common/utils/marshal.go
Normal file
29
common/utils/marshal.go
Normal file
@ -0,0 +1,29 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
timeFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
func Marshal(a any) string {
|
||||
s, _ := json.Marshal(a)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
type Time time.Time
|
||||
|
||||
func (t Time) MarshalJSON() ([]byte, error) {
|
||||
var stamp = fmt.Sprintf("\"%s\"", time.Time(t).Format(timeFormat))
|
||||
return []byte(stamp), nil
|
||||
}
|
||||
|
||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
now, err := time.ParseInLocation(`"`+timeFormat+`"`, string(data), time.Local)
|
||||
*t = Time(now)
|
||||
return err
|
||||
}
|
19
server/gate/model/db.go
Normal file
19
server/gate/model/db.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"game/server/gate/config"
|
||||
"github.com/fox/fox/db"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
var UserRedis *redis.Client
|
||||
var err error
|
||||
|
||||
func InitRedis() {
|
||||
UserRedis, err = db.InitRedis(config.Cfg.Redis.Password, config.Cfg.Redis.Host, config.Cfg.Redis.Port, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
45
server/gate/model/userGate.go
Normal file
45
server/gate/model/userGate.go
Normal file
@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"game/common/utils"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"time"
|
||||
)
|
||||
|
||||
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()
|
||||
}
|
29
server/gate/model/userGate_test.go
Normal file
29
server/gate/model/userGate_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
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))
|
||||
}
|
@ -2,15 +2,22 @@ package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/common/proto/ipb"
|
||||
"game/common/proto/pb"
|
||||
"game/common/serviceName"
|
||||
"game/common/topicName"
|
||||
"game/common/utils"
|
||||
"game/server/gate/config"
|
||||
"game/server/gate/model"
|
||||
"github.com/fox/fox/etcd"
|
||||
"github.com/fox/fox/log"
|
||||
"github.com/fox/fox/service"
|
||||
"github.com/fox/fox/ws"
|
||||
"github.com/fox/fox/xrand"
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
var Gate *GateService
|
||||
var Gates []*GateService
|
||||
|
||||
type GateService struct {
|
||||
*service.NatsService
|
||||
@ -19,18 +26,28 @@ type GateService struct {
|
||||
}
|
||||
|
||||
func Init() {
|
||||
Gate = newGateService()
|
||||
for i := 0; i < config.Command.ServiceNum; i++ {
|
||||
sid := config.Command.ServiceId + i
|
||||
if gate := newGateService(sid); gate != nil {
|
||||
Gates = append(Gates, gate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Stop() {
|
||||
Gate.NotifyStop()
|
||||
Gate.WaitStop()
|
||||
for _, gate := range Gates {
|
||||
gate.NotifyStop()
|
||||
}
|
||||
for _, gate := range Gates {
|
||||
gate.WaitStop()
|
||||
}
|
||||
}
|
||||
|
||||
func newGateService() *GateService {
|
||||
func newGateService(serviceId int) *GateService {
|
||||
var err error
|
||||
s := new(GateService)
|
||||
if s.NatsService, err = service.NewNatsService(serviceName.Gate, "1", s, config.Cfg.Nats.Address...); err != nil {
|
||||
sName := fmt.Sprintf("%v-%d", serviceName.Gate, serviceId)
|
||||
if s.NatsService, err = service.NewNatsService(serviceName.Gate, sName, s, config.Cfg.Nats.Address...); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return nil
|
||||
}
|
||||
@ -43,6 +60,7 @@ func newGateService() *GateService {
|
||||
wsAddress := fmt.Sprintf("%v:%v", config.Cfg.Special.Address, config.Cfg.Special.Port)
|
||||
s.wss = ws.NewWsServer(wsAddress, s.WsOnMessage, s.WsOnDisconnect)
|
||||
endpoint := &etcd.ServiceNode{
|
||||
TypeId: int(pb.ServiceTypeId_STI_Gate),
|
||||
Name: s.Name(),
|
||||
Type: s.Type(),
|
||||
Address: "",
|
||||
@ -80,16 +98,106 @@ func (s *GateService) OnStop() {
|
||||
log.Debug("OnStop")
|
||||
}
|
||||
|
||||
// 通过handler转发消息
|
||||
func (s *GateService) OnMessage(msg []byte) error {
|
||||
log.Debug(s.Log("on message:%v", string(msg)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *GateService) WsOnMessage(conn ws.IConn, msg []byte) {
|
||||
|
||||
log.Debug(s.Log("on message:%v", string(msg)))
|
||||
func (s *GateService) findService(serviceTypeId pb.ServiceTypeId) *etcd.ServiceNode {
|
||||
var nodes []*etcd.ServiceNode
|
||||
var newVer string
|
||||
s.etcdService.GetNodes().Range(func(_, value interface{}) bool {
|
||||
if node, ok := value.(*etcd.ServiceNode); ok && node.TypeId == int(serviceTypeId) {
|
||||
if newVer < node.Version {
|
||||
newVer = node.Version
|
||||
}
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
return true
|
||||
})
|
||||
var newNodes []*etcd.ServiceNode
|
||||
for _, node := range nodes {
|
||||
if node.Version == newVer {
|
||||
newNodes = append(newNodes, node)
|
||||
}
|
||||
}
|
||||
if len(newNodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
return nodes[xrand.IntN(len(nodes))]
|
||||
}
|
||||
|
||||
/*
|
||||
查找topic,根据serviceTypeId以及玩家id查找玩家过往访问该服务的节点,优先使用原节点
|
||||
*/
|
||||
func (s *GateService) findTopic(userId int64, serviceTypeId pb.ServiceTypeId) string {
|
||||
if userId != 0 {
|
||||
if sName, ok := userServiceMgr.FindServiceName(userId, serviceTypeId); ok {
|
||||
return service.TopicEx(sName)
|
||||
}
|
||||
}
|
||||
if sNode := s.findService(serviceTypeId); sNode != nil {
|
||||
return service.TopicEx(sNode.Name)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 运行在conn的read协程里
|
||||
func (s *GateService) WsOnMessage(conn ws.IConn, data []byte) {
|
||||
msg := &pb.ClientMsg{}
|
||||
if err := proto.Unmarshal(data, msg); err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
if topic := s.findTopic(conn.UserId(), msg.ServiceId); topic != "" {
|
||||
iMsg := &ipb.InternalMsg{ConnId: conn.Id(), UserId: conn.UserId(), MsgId: msg.MsgId, Msg: msg.Data}
|
||||
dMsg, _ := proto.Marshal(iMsg)
|
||||
_ = s.Send(topic, dMsg)
|
||||
}
|
||||
log.Debug(s.Log("client to gate:%v", utils.Marshal(msg)))
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *GateService) SendServiceData(topic string, conn ws.IConn, msgId int32, data []byte) {
|
||||
iMsg := &ipb.InternalMsg{ConnId: conn.Id(), UserId: conn.UserId(), MsgId: msgId, Msg: data}
|
||||
dMsg, _ := proto.Marshal(iMsg)
|
||||
_ = s.Send(topic, dMsg)
|
||||
}
|
||||
|
||||
// 向内部服务发送消息
|
||||
func (s *GateService) SendServiceMsg(topic string, conn ws.IConn, msgId int32, msg proto.Message) {
|
||||
iMsg := &ipb.InternalMsg{ConnId: conn.Id(), UserId: conn.UserId(), MsgId: msgId}
|
||||
iMsg.Msg, _ = proto.Marshal(msg)
|
||||
dMsg, _ := proto.Marshal(iMsg)
|
||||
_ = s.Send(topic, dMsg)
|
||||
}
|
||||
|
||||
// 向玩家发送消息
|
||||
func (s *GateService) SendClientMsg(conn ws.IConn, msgId int32, msg proto.Message) {
|
||||
cMsg := &pb.ClientMsg{MsgId: msgId}
|
||||
cMsg.Data, _ = proto.Marshal(msg)
|
||||
dMsg, _ := proto.Marshal(cMsg)
|
||||
_ = conn.SendMsg(dMsg)
|
||||
}
|
||||
|
||||
/*
|
||||
todo:针对顶号的情况,由其它网关通知本网关向玩家发送下线消息,玩家关闭连接后,触发WsOnDisconnect,此时WsOnDisconnect鉴定时顶号后不需要做任务特殊处理
|
||||
*/
|
||||
func (s *GateService) WsOnDisconnect(conn ws.IConn) {
|
||||
log.Debug(s.Log("on message:%v", string(msg)))
|
||||
if conn.UserId() > 0 {
|
||||
userServiceMgr.CleanUser(conn.UserId())
|
||||
ug, err := model.NewUserGate().Get(conn.UserId(), s.Name())
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
} else {
|
||||
// 相同网关,则为正常下线,删除redis信息然后向内网广播下线
|
||||
// 不同网关,异地登陆顶号 todo:异地登陆顶号,由其它网关通知本网关向玩家发送下线消息,并主动关闭连接,不广播下线消息,不会触发
|
||||
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()})
|
||||
}
|
||||
}
|
||||
log.Debug(s.Log("user:%v disconnect", conn.UserId()))
|
||||
}
|
||||
}
|
||||
|
54
server/gate/server/userService.go
Normal file
54
server/gate/server/userService.go
Normal file
@ -0,0 +1,54 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"game/common/proto/pb"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var userServiceMgr userServiceManager
|
||||
|
||||
/*
|
||||
记录玩家访问过的节点信息,玩家下线后清除相关信息,比如玩家在某个玩法服里掉线,重连后要回到该房间,应由对应的服务节点主动将玩家拉回房间
|
||||
*/
|
||||
type userServiceManager struct {
|
||||
inService sync.Map // key:userId+service_type_id value:service_name
|
||||
}
|
||||
|
||||
func (m *userServiceManager) makeKey(userId int64, typeId pb.ServiceTypeId) string {
|
||||
return fmt.Sprintf("%s_%d", userId, typeId)
|
||||
}
|
||||
|
||||
func (m *userServiceManager) Add(userId int64, typeId pb.ServiceTypeId, serviceName string) {
|
||||
k := m.makeKey(userId, typeId)
|
||||
m.inService.Store(k, serviceName)
|
||||
}
|
||||
|
||||
// 玩家下线,清除他呆过的所有服务节点信息
|
||||
func (m *userServiceManager) CleanUser(userId int64) {
|
||||
var del []string
|
||||
m.inService.Range(func(k, v interface{}) bool {
|
||||
userServiceType := k.(string)
|
||||
if strings.Contains(userServiceType, fmt.Sprintf("%d", userId)) {
|
||||
del = append(del, userServiceType)
|
||||
}
|
||||
return true
|
||||
})
|
||||
for _, k := range del {
|
||||
m.inService.Delete(k)
|
||||
}
|
||||
}
|
||||
|
||||
// todo:要考虑到旧服务可能已关闭,这里要访问etcd中是否有该服务节点,最好采用订阅机制,让etcd变动时清除对应服务节点
|
||||
func (m *userServiceManager) FindServiceName(userId int64, typeId pb.ServiceTypeId) (serviceName string, ok bool) {
|
||||
var v any
|
||||
if v, ok = m.inService.Load(m.makeKey(userId, typeId)); ok {
|
||||
serviceName = v.(string)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *userServiceManager) Del(userId int64, typeId pb.ServiceTypeId) {
|
||||
m.inService.Delete(m.makeKey(userId, typeId))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user