diff --git a/server/tools/protobuild/ss_msgid.proto b/server/tools/protobuild/ss_msgid.proto index f364360..55b8f45 100644 --- a/server/tools/protobuild/ss_msgid.proto +++ b/server/tools/protobuild/ss_msgid.proto @@ -3,7 +3,13 @@ package ss; //消息id定义 enum SSMessageId_e { + _SS_WSP_SocketDisconnect = 10; - _SS_Ping = 100; - _SS_Pong = 101; + _SS_CMPing = 101; + _SS_SMRpcError = 102; + _SS_CMLogin = 103; + _SS_CMReConnect = 104; + + _SS_Ping = 150; + _SS_Pong = 151; } diff --git a/server/tools/protobuild/ss_proto.proto b/server/tools/protobuild/ss_proto.proto index 6631495..2d85631 100644 --- a/server/tools/protobuild/ss_proto.proto +++ b/server/tools/protobuild/ss_proto.proto @@ -1,5 +1,27 @@ package ss; +message SS_WSP_SocketDisconnect +{ +} + +message SS_CMPing +{ +} + +message SS_CMLogin_CMReConnect_CommonHead +{ + optional int32 server_id = 1; +} + +message SS_SMRpcError +{ + optional int32 error_code = 1; + optional string error_msg = 2; + optional string debug_msg = 3; + optional string file = 4; + optional int32 lineno = 5; +} + message SS_Ping { } diff --git a/server/wsproxy/GCListener.cc b/server/wsproxy/GCListener.cc index d0f7ad7..e284eb8 100644 --- a/server/wsproxy/GCListener.cc +++ b/server/wsproxy/GCListener.cc @@ -94,6 +94,22 @@ void GCListener::UnInit() tcp_listener_ = nullptr; } +void GCListener::ForwardTargetConnMsg(MsgHdr& hdr) +{ + char* buff = (char*)malloc(sizeof(PackHead) + hdr.buflen); + PackHead* head = (PackHead*)buff; + head->packlen = hdr.buflen; + head->msgid = hdr.msgid; + head->seqid = hdr.seqid; + head->magic_code = MAGIC_CODE; + #if 1 + head->rpc_error_code = hdr.ip_saddr; + #endif + + tcp_listener_->SendClientMsg(hdr.socket_handle, buff, sizeof(PackHead*) + head->packlen); + free(buff); +} + void GCListener::SendText(unsigned short sockhandle, const std::string& text) { tcp_listener_->SendClientMsg(sockhandle, text.data(), text.size()); diff --git a/server/wsproxy/GCListener.h b/server/wsproxy/GCListener.h index 26516cb..275c6a3 100644 --- a/server/wsproxy/GCListener.h +++ b/server/wsproxy/GCListener.h @@ -25,11 +25,13 @@ class GCListener : public a8::Singleton void UnInit(); template - void SendToClient(unsigned short sockhandle, T& msg) + void SendMsg(unsigned short socket_handle, T& msg) { static int msgid = ::Net_GetMessageId(msg); - Net_SendMsg(tcp_listener_, sockhandle, msgid, msg); + Net_SendMsg(tcp_listener_, socket_handle, 0, msgid, msg); } + + void ForwardTargetConnMsg(MsgHdr& hdr); void SendText(unsigned short sockhandle, const std::string& text); void ForceCloseClient(unsigned short sockhandle); diff --git a/server/wsproxy/app.cc b/server/wsproxy/app.cc index 91159ce..0864ffc 100644 --- a/server/wsproxy/app.cc +++ b/server/wsproxy/app.cc @@ -16,8 +16,11 @@ #include "jsondatamgr.h" #include "handlermgr.h" #include "target_conn.h" +#include "target_conn_mgr.h" #include "gameclient.h" #include "gameclientmgr.h" +#include "ss_msgid.pb.h" +#include "ss_proto.pb.h" struct MsgNode { @@ -87,6 +90,7 @@ void App::Init(int argc, char* argv[]) GCListener::Instance()->Init(); uuid.SetMachineId(instance_id); GameClientMgr::Instance()->Init(); + TargetConnMgr::Instance()->Init(); a8::UdpLog::Instance()->Info("masterserver starting instance_id:%d pid:%d", {instance_id, getpid()}); { @@ -108,6 +112,7 @@ void App::UnInit() if (terminated) { return; } + TargetConnMgr::Instance()->UnInit(); GameClientMgr::Instance()->UnInit(); GCListener::Instance()->UnInit(); JsonDataMgr::Instance()->UnInit(); @@ -313,23 +318,39 @@ void App::ProcessClientMsg(MsgHdr& hdr) if (hdr.msgid < 100) { return; } - GameClient* client = GameClientMgr::Instance()->GetGameClientBySocket(hdr.socket_handle); - if (client && client->conn) { - client->conn->ForwardClientMsg(hdr); + TargetConn* conn = nullptr; + if (hdr.msgid == ss::_SS_CMLogin || hdr.msgid == ss::_SS_CMReConnect) { + ss::SS_CMLogin_CMReConnect_CommonHead msg; + bool ok = msg.ParseFromArray(hdr.buf + hdr.offset, hdr.buflen - hdr.offset); + if (ok) { + conn = TargetConnMgr::Instance()->GetConnByInstanceId(msg.server_id()); + if (!conn) { + ss::SS_SMRpcError respmsg; + respmsg.set_error_code(10); + GCListener::Instance()->SendMsg(hdr.socket_handle, respmsg); + } + } else { + return; + } + } else { + GameClient* client = GameClientMgr::Instance()->GetGameClientBySocket(hdr.socket_handle); + conn = client->conn; + } + if (conn) { + conn->ForwardClientMsg(hdr); } } void App::ProcessTargetServerMsg(MsgHdr& hdr) { - NetMsgHandler* handler = GetNetMsgHandler(&HandlerMgr::Instance()->rsmsghandler, - hdr.msgid); - if (handler) { - switch (handler->handlerid) { - case HID_GCListener: - ProcessNetMsg(handler, GCListener::Instance(), hdr); - break; - } + if (hdr.msgid < 100) { + return; } + if (hdr.msgid == ss::_SS_CMLogin || hdr.msgid == ss::_SS_CMReConnect) { + GameClientMgr::Instance()->BindTargetConn(hdr.socket_handle, hdr.ip_saddr); + GCListener::Instance()->MarkClient(hdr.socket_handle, true); + } + GCListener::Instance()->ForwardTargetConnMsg(hdr); } void App::ProcessIMMsg() @@ -346,9 +367,12 @@ void App::ProcessIMMsg() switch (im_work_node_->msgid) { case IM_ClientSocketDisconnect: { - #if 0 - PlayerMgr::Instance()->OnClientDisconnect(pdelnode->params); - #endif + GameClientMgr::Instance()->OnClientDisconnect(pdelnode->params); + } + break; + case IM_TargetConnDisconnect: + { + GameClientMgr::Instance()->OnTargetServerDisconnect(pdelnode->params); } break; case IM_ExecGM: diff --git a/server/wsproxy/gameclient.h b/server/wsproxy/gameclient.h index 61ad8b8..f225c95 100644 --- a/server/wsproxy/gameclient.h +++ b/server/wsproxy/gameclient.h @@ -4,6 +4,7 @@ class TargetConn; class GameClient { public: + int socket_handle = a8::INVALID_SOCKET_HANDLE; TargetConn* conn = nullptr; }; diff --git a/server/wsproxy/gameclientmgr.cc b/server/wsproxy/gameclientmgr.cc index acddbbd..7a22c83 100644 --- a/server/wsproxy/gameclientmgr.cc +++ b/server/wsproxy/gameclientmgr.cc @@ -1,6 +1,12 @@ #include "precompile.h" #include "gameclientmgr.h" +#include "ss_proto.pb.h" + +#include "gameclient.h" +#include "target_conn.h" +#include "target_conn_mgr.h" +#include "GCListener.h" void GameClientMgr::Init() { @@ -10,8 +16,52 @@ void GameClientMgr::UnInit() { } +void GameClientMgr::OnClientDisconnect(a8::XParams& param) +{ + GameClient* client = GetGameClientBySocket(param.sender); + if (client) { + if (client->conn) { + ss::SS_WSP_SocketDisconnect msg; + client->conn->SendMsg(msg); + } + socket_hash_.erase(param.sender); + delete client; + } +} + +void GameClientMgr::OnTargetServerDisconnect(a8::XParams& param) +{ + std::list delete_client; + for (auto& pair : socket_hash_) { + if (pair.second->conn && pair.second->conn->instance_id == param.sender.GetInt()) { + delete_client.push_back(pair.second); + } + } + for (auto& client : delete_client) { + GCListener::Instance()->ForceCloseClient(client->socket_handle); + socket_hash_.erase(client->socket_handle); + delete client; + } +} + GameClient* GameClientMgr::GetGameClientBySocket(int sockhandle) { auto itr = socket_hash_.find(sockhandle); return itr != socket_hash_.end() ? itr->second : nullptr; } + +void GameClientMgr::BindTargetConn(int socket_handle, int conn_instance_id) +{ + TargetConn* conn = TargetConnMgr::Instance()->GetConnByInstanceId(conn_instance_id); + if (conn) { + GameClient* client = GetGameClientBySocket(socket_handle); + if (client) { + client->conn = conn; + } else { + client = new GameClient(); + client->socket_handle = socket_handle; + client->conn = conn; + socket_hash_[client->socket_handle] = client; + } + } +} diff --git a/server/wsproxy/gameclientmgr.h b/server/wsproxy/gameclientmgr.h index 9a3bd50..aeeeeb0 100644 --- a/server/wsproxy/gameclientmgr.h +++ b/server/wsproxy/gameclientmgr.h @@ -12,7 +12,10 @@ class GameClientMgr : public a8::Singleton void Init(); void UnInit(); + void OnClientDisconnect(a8::XParams& param); + void OnTargetServerDisconnect(a8::XParams& param); GameClient* GetGameClientBySocket(int sockhande); + void BindTargetConn(int socket_handle, int conn_instance_id); private: std::map socket_hash_; diff --git a/server/wsproxy/target_conn.cc b/server/wsproxy/target_conn.cc index 9476e27..0ec6d74 100644 --- a/server/wsproxy/target_conn.cc +++ b/server/wsproxy/target_conn.cc @@ -119,18 +119,18 @@ void TargetConn::on_socketread(a8::TcpClient* sender, char* buf, unsigned int le bool warning = false; unsigned int offset = 0; - while (recv_bufflen_ - offset > sizeof(PackHead)) { - PackHead* p = (PackHead*) &recv_buff_[offset]; + while (recv_bufflen_ - offset > sizeof(WSProxyPackHead_S)) { + WSProxyPackHead_S* p = (WSProxyPackHead_S*) &recv_buff_[offset]; if (p->magic_code == MAGIC_CODE) { if (recv_bufflen_ - offset < sizeof(PackHead) + p->packlen) { break; } App::Instance()->AddSocketMsg(SF_TargetServer, + p->socket_handle, instance_id, - 0, p->msgid, p->seqid, - &recv_buff_[offset + sizeof(PackHead)], + &recv_buff_[offset + sizeof(WSProxyPackHead_S)], p->packlen); offset += sizeof(PackHead) + p->packlen; } else { diff --git a/server/wsproxy/target_conn.h b/server/wsproxy/target_conn.h index 3901462..44a527b 100644 --- a/server/wsproxy/target_conn.h +++ b/server/wsproxy/target_conn.h @@ -23,6 +23,13 @@ class TargetConn void Close(); bool Connected(); + template + void SendMsg(T& msg) + { + static int msgid = ::Net_GetMessageId(msg); + Net_SendMsg(tcp_client_, 0, msgid, msg); + } + void ForwardClientMsg(MsgHdr& hdr); private: diff --git a/server/wsproxy/target_conn_mgr.cc b/server/wsproxy/target_conn_mgr.cc index 59ce089..f187278 100644 --- a/server/wsproxy/target_conn_mgr.cc +++ b/server/wsproxy/target_conn_mgr.cc @@ -10,7 +10,7 @@ void TargetConnMgr::UnInit() { } -TargetConn* TargetConnMgr::GetConnBySocket(int instance_id) +TargetConn* TargetConnMgr::GetConnByInstanceId(int instance_id) { auto itr = target_conn_hash_.find(instance_id); return itr != target_conn_hash_.end() ? itr->second : nullptr; diff --git a/server/wsproxy/target_conn_mgr.h b/server/wsproxy/target_conn_mgr.h index 652ea04..9519bdb 100644 --- a/server/wsproxy/target_conn_mgr.h +++ b/server/wsproxy/target_conn_mgr.h @@ -12,7 +12,7 @@ class TargetConnMgr : public a8::Singleton void Init(); void UnInit(); - TargetConn* GetConnBySocket(int instance_id); + TargetConn* GetConnByInstanceId(int instance_id); private: std::map target_conn_hash_;