From ac17302e297065946f0c6616e571419fc2179b11 Mon Sep 17 00:00:00 2001 From: azw Date: Sun, 19 Feb 2023 01:35:52 +0000 Subject: [PATCH] 1 --- server/imserver/app.cc | 454 +++++++++++++++++++++++++++++++++++ server/imserver/app.h | 98 ++++++++ server/imserver/constant.h | 1 + server/imserver/main.cc | 12 + server/imserver/mt/Forward.h | 1 + server/imserver/mt/MetaMgr.h | 1 + server/imserver/precompile.h | 11 + server/imserver/types.h | 1 + 8 files changed, 579 insertions(+) create mode 100644 server/imserver/app.cc create mode 100644 server/imserver/app.h create mode 100644 server/imserver/constant.h create mode 100644 server/imserver/main.cc create mode 100644 server/imserver/mt/Forward.h create mode 100644 server/imserver/mt/MetaMgr.h create mode 100644 server/imserver/precompile.h create mode 100644 server/imserver/types.h diff --git a/server/imserver/app.cc b/server/imserver/app.cc new file mode 100644 index 0000000..b6335ac --- /dev/null +++ b/server/imserver/app.cc @@ -0,0 +1,454 @@ +#include "precompile.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "app.h" +#include "handlermgr.h" +#if 0 +#include "ss_msgid.pb.h" +#include "ss_proto.pb.h" +#endif +#include "f8/msgqueue.h" +#include "f8/tglog.h" +#include "f8/httpclientpool.h" +#include + +#include "selfchecker.h" + +#include "mt/MetaMgr.h" + +struct MsgNode +{ + SocketFrom_e sockfrom; + int sockhandle; + unsigned short msgid; + unsigned int seqid; + long ip_saddr; + char* buf; + int buflen; + MsgNode* next; +}; + +const char* const PROJ_LOG_ROOT_FMT = "/data/logs/%s/logs"; +const char* const PROJ_LOG_FILENAME_FMT = "log_$pid_%Y%m%d.log"; + +static void SavePerfLog() +{ +} + +bool App::Init(int argc, char* argv[]) +{ + signal(SIGPIPE, SIG_IGN); + this->argc = argc; + this->argv = argv; + + if (!ParseOpt()) { + if (node_id <= 0) { + a8::XPrintf("imserver启动失败,缺少-n参数\n", {}); + } else if (node_id > MAX_NODE_ID) { + a8::XPrintf("imserver启动失败,-n参数不能大于%d\n", {MAX_NODE_ID}); + } else if (instance_id <= 0) { + a8::XPrintf("imserver启动失败,缺少-i参数\n", {}); + } else if (instance_id > MAX_INSTANCE_ID) { + a8::XPrintf("imserver启动失败,-i参数不能大于%d\n", {MAX_INSTANCE_ID}); + } + return false; + } + int debug_mode = 0; +#ifdef DEBUG + debug_mode = 1; +#endif + a8::XPrintf("imserver starting node_id: %d instance_id:%d pid:%d game_id:%d debug_mode:%d\n", + { + node_id, + instance_id, + getpid(), + GAME_ID, + debug_mode + }); + + loop_mutex_ = new std::mutex(); + loop_cond_ = new std::condition_variable(); + msg_mutex_ = new std::mutex(); + + srand(time(nullptr)); + InitLog(); +#ifdef DEBUG + TraceMgr::Instance()->Init("imserver2006"); +#endif + f8::MsgQueue::Instance()->Init(); + HandlerMgr::Instance()->Init(); + f8::Timer::Instance()->Init(); + f8::TGLog::Instance()->Init(a8::Format(PROJ_NAME_FMT, {GAME_ID}), false, 0); + f8::HttpClientPool::Instance()->Init(MAX_ALL_HTTP_NUM, MAX_SYS_HTTP_NUM, MAX_USER_HTTP_NUM); + mt::MetaMgr::Instance()->Init(); + SelfChecker::Init(); + uuid.SetMachineId((node_id - 1) * MAX_NODE_ID + instance_id); + GGListener::Instance()->Init(); + HttpProxy::Instance()->Init(); + + f8::UdpLog::Instance()->Info("imserver starting instance_id:%d pid:%d debug_mode:%d channel:%d", + { + instance_id, + getpid(), + debug_mode, + JsonDataMgr::Instance()->channel + }); + { + int perf_log_time = 1000 * 30; + f8::Timer::Instance()->SetInterval + (perf_log_time, + [] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + SavePerfLog(); + } + }); + } + if (HasFlag(7)) { + f8::Timer::Instance()->SetTimeout + ( + 1000 * 60 * 1, + [] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + App::Instance()->terminated = true; + } + } + ); + } + return true; +} + +void App::UnInit() +{ + //const char* s2 = GetEnumString(); + //int i = static_cast(Test_e::kFlyBuffId); + HttpProxy::Instance()->UnInit(); + GGListener::Instance()->UnInit(); + PlayerMgr::Instance()->UnInit(); + MapMgr::Instance()->UnInit(); + MatchMgr::Instance()->UnInit(); + RoomMgr::Instance()->UnInit(); + KillMgr::Instance()->UnInit(); + EntityFactory::Instance()->UnInit(); + SelfChecker::UnInit(); + mt::MetaMgr::Instance()->UnInit(); + JsonDataMgr::Instance()->UnInit(); + f8::BtMgr::Instance()->UnInit(); + f8::HttpClientPool::Instance()->UnInit(); + HandlerMgr::Instance()->UnInit(); + f8::MsgQueue::Instance()->UnInit(); + f8::Timer::Instance()->UnInit(); + PerfMonitor::Instance()->UnInit(); + f8::TGLog::Instance()->UnInit(); +#ifdef DEBUG + TraceMgr::Instance()->UnInit(); +#endif + UnInitLog(); + + FreeSocketMsgQueue(); + A8_SAFE_DELETE(msg_mutex_); + A8_SAFE_DELETE(loop_cond_); + A8_SAFE_DELETE(loop_mutex_); +} + +int App::Run() +{ + int ret = 0; + f8::UdpLog::Instance()->Info("imserver running", {}); + last_run_tick_ = a8::XGetTickCount(); + int delta_time = 0; + while (!terminated) { + a8::tick_t begin_tick = a8::XGetTickCount(); + Global::g_nowtime = time(nullptr); + QuickExecute(delta_time); + SlowerExecute(delta_time); + Schedule(); + a8::tick_t end_tick = a8::XGetTickCount(); + if (end_tick - begin_tick > PerfMonitor::Instance()->max_run_delay_time) { + PerfMonitor::Instance()->max_run_delay_time = end_tick - begin_tick; + } + delta_time = end_tick - begin_tick; + } + return ret; +} + +void App::AddSocketMsg(SocketFrom_e sockfrom, + int sockhandle, + long ip_saddr, + unsigned short msgid, + unsigned int seqid, + const char *msgbody, + int bodylen) +{ + MsgNode *p = (MsgNode*) malloc(sizeof(MsgNode)); + memset(p, 0, sizeof(MsgNode)); + p->sockfrom = sockfrom; + p->ip_saddr = ip_saddr; + p->sockhandle = sockhandle; + p->msgid = msgid; + p->seqid = seqid; + p->buf = nullptr; + p->buflen = bodylen; + if (bodylen > 0) { + p->buf = (char*)malloc(bodylen); + memmove(p->buf, msgbody, bodylen); + } + msg_mutex_->lock(); + if (bot_node_) { + bot_node_->next = p; + bot_node_ = p; + } else { + top_node_ = p; + bot_node_ = p; + } + ++msgnode_size_; + msg_mutex_->unlock(); + NotifyLoopCond(); +} + +void App::QuickExecute(int delta_time) +{ + f8::MsgQueue::Instance()->Update(); + DispatchMsg(); + RoomMgr::Instance()->Update(delta_time); + f8::Timer::Instance()->Update(); +} + +void App::SlowerExecute(int delta_time) +{ +} + +void App::NotifyLoopCond() +{ + std::unique_lock lk(*loop_mutex_); + loop_cond_->notify_all(); +} + +void App::Schedule() +{ + std::unique_lock lk(*loop_mutex_); + loop_cond_->wait_for(lk, std::chrono::milliseconds(1)); +} + +bool App::HasTask() +{ + { + if (!work_node_) { + msg_mutex_->lock(); + if (!work_node_ && top_node_) { + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + } + msg_mutex_->unlock(); + } + if (work_node_) { + return true; + } + } + return false; +} + +void App::DispatchMsg() +{ + long long begin_tick = a8::XGetTickCount(); + if (!work_node_ && top_node_) { + msg_mutex_->lock(); + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + working_msgnode_size_ = msgnode_size_; + msg_mutex_->unlock(); + } + + f8::MsgHdr hdr; + while (work_node_) { + MsgNode *pdelnode = work_node_; + work_node_ = pdelnode->next; + hdr.msgid = pdelnode->msgid; + hdr.seqid = pdelnode->seqid; + hdr.socket_handle = pdelnode->sockhandle; + hdr.buf = pdelnode->buf; + hdr.buflen = pdelnode->buflen; + hdr.offset = 0; + hdr.ip_saddr = pdelnode->ip_saddr; + switch (pdelnode->sockfrom) { + case SF_GameGate: + { + ProcessGameGateMsg(hdr); + } + break; + } + if (pdelnode->buf) { + free(pdelnode->buf); + } + free(pdelnode); + working_msgnode_size_--; + if (a8::XGetTickCount() - begin_tick > 200) { + break; + } + }//end while + + if (!work_node_) { + working_msgnode_size_ = 0; + } + a8::tick_t end_tick = a8::XGetTickCount(); + if (end_tick - begin_tick > PerfMonitor::Instance()->max_dispatchmsg_time) { + PerfMonitor::Instance()->max_dispatchmsg_time = end_tick - begin_tick; + } +} + +void App::ProcessGameGateMsg(f8::MsgHdr& hdr) +{ + if (hdr.msgid == ss::_SS_Ping) { + ss::SS_Pong pongmsg; + GGListener::Instance()->SendProxyMsg(hdr.socket_handle, pongmsg); + return; + } + f8::NetMsgHandler* handler = f8::GetNetMsgHandler(&HandlerMgr::Instance()->ggmsghandler, + hdr.msgid); + if (handler) { + switch (handler->handlerid) { + case HID_RoomMgr: + ProcessNetMsg(handler, RoomMgr::Instance(), hdr); + break; + case HID_MatchTeam: + { + auto match_info = MatchMgr::Instance()->GetMatchInfo(hdr.socket_handle); + if (match_info) { + ProcessNetMsg(handler, std::get<1>(*match_info), hdr); + } + } + break; + case HID_PlayerMgr: + ProcessNetMsg(handler, PlayerMgr::Instance(), hdr); + break; + case HID_Player: + { + Player* hum = PlayerMgr::Instance()->GetPlayerBySocket(hdr.socket_handle); + if (hum) { + hdr.hum = hum; + ProcessNetMsg(handler, hum, hdr); + } + } + break; + } + } +} + +void App::InitLog() +{ + std::string filename_fmt = PROJ_LOG_FILENAME_FMT; + a8::ReplaceString(filename_fmt, "$pid", a8::XValue(getpid())); + + std::string proj_root_dir = a8::Format(PROJ_ROOT_FMT, {a8::Format(PROJ_NAME_FMT,{GAME_ID})}); + std::string proj_log_root_dir = a8::Format(PROJ_LOG_ROOT_FMT, {a8::Format(PROJ_NAME_FMT, {GAME_ID})}); + std::string log_file_name = a8::Format(PROJ_LOG_ROOT_FMT, + {a8::Format(PROJ_NAME_FMT, {GAME_ID})}) + "/" + filename_fmt; + + a8::MkDir(proj_root_dir); + a8::MkDir(proj_log_root_dir); + f8::UdpLog::Instance()->SetLogFileName(log_file_name); + f8::UdpLog::Instance()->Init(); + f8::UdpLog::Instance()->Info("proj_root_dir:%s", {proj_root_dir}); + f8::UdpLog::Instance()->Info("proj_log_root_dir:%s", {proj_log_root_dir}); + f8::UdpLog::Instance()->Info("log_file_name:%s", {log_file_name}); +} + +void App::UnInitLog() +{ + f8::UdpLog::Instance()->UnInit(); +} + +bool App::ParseOpt() +{ + int ch = 0; + while ((ch = getopt(argc, argv, "i:t:r:f:n:")) != -1) { + switch (ch) { + case 'n': + { + node_id = a8::XValue(optarg); + } + break; + case 'i': + { + instance_id = a8::XValue(optarg); + } + break; + case 't': + { + is_test_mode = true; + test_param = a8::XValue(optarg); + } + break; + case 'f': + { + std::vector strings; + a8::Split(optarg, strings, ','); + for (auto& str : strings) { + flags.insert(a8::XValue(str).GetInt()); + } + } + break; + } + } + return instance_id > 0 && node_id > 0; +} + +long long App::NewUuid() +{ + return uuid.Generate(); +} + +bool App::HasFlag(int flag) +{ + return flags.find(flag) != flags.end(); +} + +void App::SetFlag(int flag) +{ + flags.insert(flag); +} + +void App::UnSetFlag(int flag) +{ + flags.erase(flag); +} + +void App::FreeSocketMsgQueue() +{ + msg_mutex_->lock(); + if (!work_node_) { + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + } + while (work_node_) { + MsgNode* pdelnode = work_node_; + work_node_ = work_node_->next; + if (pdelnode->buf) { + free(pdelnode->buf); + } + free(pdelnode); + if (!work_node_) { + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + } + } + msg_mutex_->unlock(); +} diff --git a/server/imserver/app.h b/server/imserver/app.h new file mode 100644 index 0000000..1e70b37 --- /dev/null +++ b/server/imserver/app.h @@ -0,0 +1,98 @@ +#pragma once + +#include +#include + +#include + +struct MsgNode; +class App : public a8::Singleton +{ +private: + App() {}; + friend class a8::Singleton; + +public: + #ifdef DEBUG + std::map debug_params; + #endif + + bool Init(int argc, char* argv[]); + void UnInit(); + + int Run(); + + void AddSocketMsg(SocketFrom_e sockfrom, + int sockhandle, + long ip_saddr, + unsigned short msgid, + unsigned int seqid, + const char *msgbody, + int bodylen); + + void NotifyLoopCond(); + + long long NewUuid(); + bool HasFlag(int flag); + void SetFlag(int flag); + void UnSetFlag(int flag); + +private: + void QuickExecute(int delta_time); + void SlowerExecute(int delta_time); + void Schedule(); + bool HasTask(); + + void DispatchMsg(); + + void ProcessGameGateMsg(f8::MsgHdr& hdr); + + void InitLog(); + void UnInitLog(); + + bool ParseOpt(); + void FreeSocketMsgQueue(); + +public: + int argc = 0; + char** argv = nullptr; + volatile bool terminated = false; + a8::uuid::SnowFlake uuid; + +public: + int instance_id = 0; + int node_id = 0; + bool is_test_mode = false; + int test_param = 0; + bool servicing = true; + +private: + /* + 1: 是否自动匹配机器人组队 + 2: 是否发布环境 + 3: battleReport环境 + 4: 打印性能日志 + 5: 压力测试 + 6: + 7: 内存泄露测试 + 8: httpclientpool压力测试 + */ + std::set flags; + +private: + long long last_run_tick_ = 0; + std::mutex *loop_mutex_ = nullptr; + std::condition_variable *loop_cond_ = nullptr; + + std::mutex *msg_mutex_ = nullptr; + MsgNode* top_node_ = nullptr; + MsgNode* bot_node_ = nullptr; + MsgNode* work_node_ = nullptr; + + long long curr_uniid_ = 0; + +public: + int msgnode_size_ = 0 ; + int working_msgnode_size_ = 0; + +}; diff --git a/server/imserver/constant.h b/server/imserver/constant.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/server/imserver/constant.h @@ -0,0 +1 @@ +#pragma once diff --git a/server/imserver/main.cc b/server/imserver/main.cc new file mode 100644 index 0000000..3ca4bad --- /dev/null +++ b/server/imserver/main.cc @@ -0,0 +1,12 @@ +#include "precompile.h" +#include "app.h" + +int main(int argc, char* argv[]) +{ + int exitcode = 0; + if (App::Instance()->Init(argc, argv)) { + exitcode = App::Instance()->Run(); + App::Instance()->UnInit(); + } + return exitcode; +} diff --git a/server/imserver/mt/Forward.h b/server/imserver/mt/Forward.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/server/imserver/mt/Forward.h @@ -0,0 +1 @@ +#pragma once diff --git a/server/imserver/mt/MetaMgr.h b/server/imserver/mt/MetaMgr.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/server/imserver/mt/MetaMgr.h @@ -0,0 +1 @@ +#pragma once diff --git a/server/imserver/precompile.h b/server/imserver/precompile.h new file mode 100644 index 0000000..079e622 --- /dev/null +++ b/server/imserver/precompile.h @@ -0,0 +1,11 @@ +#pragma once + +#include +#include + +#include +#include + +#include "constant.h" +#include "mt/Forward.h" +#include "types.h" diff --git a/server/imserver/types.h b/server/imserver/types.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/server/imserver/types.h @@ -0,0 +1 @@ +#pragma once