diff --git a/common/internalPb/internal.proto b/common/internalPb/internal.proto index 08dc7fc..1f93e39 100644 --- a/common/internalPb/internal.proto +++ b/common/internalPb/internal.proto @@ -5,7 +5,7 @@ option go_package = "common/proto/ipb"; enum MsgId { Unknown = 0; - Internal = -1; // 内部消息id + Internal = -1; // 内部消息id } @@ -26,3 +26,4 @@ message C2SMessage bytes msg = 4; // 消息 } + diff --git a/common/pb/login.proto b/common/pb/login.proto index c3cb69d..ab2be67 100644 --- a/common/pb/login.proto +++ b/common/pb/login.proto @@ -8,7 +8,7 @@ enum LoginMsgId { Unknown = 0; C2SUserLogin = 1; // 玩家登陆 - S2SUserLogin = 2; + S2CUserLogin = 2; NtfUserOnline = 3; C2SUserLogout = 4; S2CUserLogout = 5; @@ -28,7 +28,8 @@ message C2SUserLoginMsg message S2CUserLoginMsg { ErrCode code = 1; - int64 user_id = 2; + int64 user_id = 2; + string token = 3; // token } // 上线通知 diff --git a/common/proto/pb/login.pb.go b/common/proto/pb/login.pb.go index 6d06fef..0c1e931 100644 --- a/common/proto/pb/login.pb.go +++ b/common/proto/pb/login.pb.go @@ -26,7 +26,7 @@ type LoginMsgId int32 const ( LoginMsgId_Unknown LoginMsgId = 0 LoginMsgId_C2SUserLogin LoginMsgId = 1 // 玩家登陆 - LoginMsgId_S2SUserLogin LoginMsgId = 2 + LoginMsgId_S2CUserLogin LoginMsgId = 2 LoginMsgId_NtfUserOnline LoginMsgId = 3 LoginMsgId_C2SUserLogout LoginMsgId = 4 LoginMsgId_S2CUserLogout LoginMsgId = 5 @@ -38,7 +38,7 @@ var ( LoginMsgId_name = map[int32]string{ 0: "Unknown", 1: "C2SUserLogin", - 2: "S2SUserLogin", + 2: "S2CUserLogin", 3: "NtfUserOnline", 4: "C2SUserLogout", 5: "S2CUserLogout", @@ -47,7 +47,7 @@ var ( LoginMsgId_value = map[string]int32{ "Unknown": 0, "C2SUserLogin": 1, - "S2SUserLogin": 2, + "S2CUserLogin": 2, "NtfUserOnline": 3, "C2SUserLogout": 4, "S2CUserLogout": 5, @@ -147,6 +147,7 @@ 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"` + Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` // token unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -195,6 +196,13 @@ func (x *S2CUserLoginMsg) GetUserId() int64 { return 0 } +func (x *S2CUserLoginMsg) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + // 上线通知 type NtfUserOnlineMsg struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -375,10 +383,11 @@ const file_login_proto_rawDesc = "" + "\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" + + "\aversion\x18\x03 \x01(\tR\aversion\"a\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" + + "\auser_id\x18\x02 \x01(\x03R\x06userId\x12\x14\n" + + "\x05token\x18\x03 \x01(\tR\x05token\"+\n" + "\x10NtfUserOnlineMsg\x12\x17\n" + "\auser_id\x18\x02 \x01(\x03R\x06userId\"\x12\n" + "\x10C2SUserLogoutMsg\"3\n" + @@ -390,7 +399,7 @@ const file_login_proto_rawDesc = "" + "LoginMsgId\x12\v\n" + "\aUnknown\x10\x00\x12\x10\n" + "\fC2SUserLogin\x10\x01\x12\x10\n" + - "\fS2SUserLogin\x10\x02\x12\x11\n" + + "\fS2CUserLogin\x10\x02\x12\x11\n" + "\rNtfUserOnline\x10\x03\x12\x11\n" + "\rC2SUserLogout\x10\x04\x12\x11\n" + "\rS2CUserLogout\x10\x05\x12\x12\n" + diff --git a/server/gate/server/processor.go b/server/gate/server/processor.go index 702f65c..40910c7 100644 --- a/server/gate/server/processor.go +++ b/server/gate/server/processor.go @@ -2,20 +2,54 @@ package server import ( "game/common/proto/pb" + "game/server/gate/model" "github.com/fox/fox/processor" + "github.com/fox/fox/service" "github.com/fox/fox/ws" ) /* -gate只处理内部消息(ipb中的消息),避免拦截到外部消息,导致不转发给玩家 +如果需要gate处理后,继续将消息转发给玩家,则最后需要调用SendClientData */ func (s *GateService) initProcessor() { s.processor.RegisterMessages(processor.RegisterMetas{ pb.LoginMsgId_NtfUserOnline: {pb.NtfUserOnlineMsg{}, s.onNtfUserOnline}, + pb.LoginMsgId_S2CUserLogin: {pb.S2CUserLoginMsg{}, s.onUserLogin}, + pb.LoginMsgId_S2CUserLogout: {pb.S2CUserLogoutMsg{}, s.onUserLogout}, }) } -func (s *GateService) onNtfUserOnline(conn ws.IConn, msg *pb.NtfUserOnlineMsg) { - _ = conn - _ = msg +func (s *GateService) onNtfUserOnline(conn ws.IConn, _ *pb.NtfUserOnlineMsg) { + s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogout), &pb.S2CUserLogoutMsg{Code: pb.ErrCode_EC_LoginDiffLoc}) + conn.NotifyClose() +} + +// 收到登陆成功消息,判断是否顶号 +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 { + return + } + 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 + } + // 网关不同,说明玩家在其它网关上登陆, + if ug.GateName != s.Name() { + s.SendServiceMsg(service.TopicEx(ug.GateName), conn, int32(pb.LoginMsgId_S2CUserLogout), &pb.S2CUserLogoutMsg{Code: pb.ErrCode_EC_LoginDiffLoc}) + } + + //conn.NotifyClose() +} + +// 收到登出消息 +func (s *GateService) onUserLogout(conn ws.IConn, msg *pb.S2CUserLogoutMsg) { + s.SendClientMsg(conn, int32(pb.LoginMsgId_S2CUserLogout), msg) + // 登出的清理工作由WsOnDisconnect实现 + conn.NotifyClose() } diff --git a/server/gate/server/service.go b/server/gate/server/service.go index 972c404..d6d4a7f 100644 --- a/server/gate/server/service.go +++ b/server/gate/server/service.go @@ -119,13 +119,7 @@ func (s *GateService) OnMessage(data []byte) error { if req, err := s.processor.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil { err = s.processor.Dispatch(iMsg.MsgId, conn, req) } else { - var cMsg = &pb.ClientMsg{ - ServiceId: 0, - MsgId: iMsg.MsgId, - Data: iMsg.Msg, - } - cData, _ := proto.Marshal(cMsg) - _ = conn.SendMsg(cData) + s.SendClientData(conn, iMsg.MsgId, iMsg.Msg) } //log.Debug(s.Log("on message:%v", string(msg))) return nil @@ -200,6 +194,13 @@ func (s *GateService) SendServiceMsg(topic string, conn ws.IConn, msgId int32, m _ = s.Send(topic, dMsg) } +// 向玩家发送消息 +func (s *GateService) SendClientData(conn ws.IConn, msgId int32, data []byte) { + cMsg := &pb.ClientMsg{MsgId: msgId, Data: data} + dMsg, _ := proto.Marshal(cMsg) + _ = conn.SendMsg(dMsg) +} + // 向玩家发送消息 func (s *GateService) SendClientMsg(conn ws.IConn, msgId int32, msg proto.Message) { cMsg := &pb.ClientMsg{MsgId: msgId} @@ -208,9 +209,6 @@ func (s *GateService) SendClientMsg(conn ws.IConn, msgId int32, msg proto.Messag _ = conn.SendMsg(dMsg) } -/* -todo:针对顶号的情况,由其它网关通知本网关向玩家发送下线消息,玩家关闭连接后,触发WsOnDisconnect,此时WsOnDisconnect鉴定时顶号后不需要做任务特殊处理 -*/ func (s *GateService) WsOnDisconnect(conn ws.IConn) { if conn.UserId() > 0 { userServiceMgr.CleanUser(conn.UserId()) @@ -219,7 +217,7 @@ func (s *GateService) WsOnDisconnect(conn ws.IConn) { log.Error(err.Error()) } else { // 相同网关,则为正常下线,删除redis信息然后向内网广播下线 - // 不同网关,异地登陆顶号 todo:异地登陆顶号,由其它网关通知本网关向玩家发送下线消息,并主动关闭连接,不广播下线消息,不会触发 + // 不同网关,异地登陆顶号 由其它网关通知本网关向玩家发送下线消息(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()})