diff --git a/server/masterserver/gsmgr.cc b/server/masterserver/gsmgr.cc index 1c783ff..73ce096 100644 --- a/server/masterserver/gsmgr.cc +++ b/server/masterserver/gsmgr.cc @@ -27,6 +27,9 @@ void GSMgr::UnInit() void GSMgr::_SS_WSP_RequestTargetServer(f8::MsgHdr& hdr, const ss::SS_WSP_RequestTargetServer& msg) { int channel = f8::ExtractChannelIdFromAccountId(msg.account_id()); + if (!App::Instance()->IsSeparateChannel(channel)) { + channel = 0; + } ss::SS_MS_ResponseTargetServer respmsg; respmsg.set_context_id(msg.context_id()); if (msg.is_reconnect()) { @@ -82,11 +85,16 @@ void GSMgr::___GSReport(f8::JsonHttpRequest* request) if (itr->second.online_num != online_num || itr->second.room_num != room_num || itr->second.alive_count != alive_count || - itr->second.servicing != servicing + itr->second.servicing != servicing || + itr->second.channel != channel ) { itr->second.online_num = online_num; itr->second.room_num = room_num; itr->second.servicing = servicing; + if (itr->second.channel != channel) { + itr->second.channel = channel; + OnChannelChange(&itr->second); + } RearrangeNode(); } itr->second.alive_count = alive_count; @@ -107,7 +115,7 @@ void GSMgr::___GSReport(f8::JsonHttpRequest* request) gs.channel = channel; gs.last_active_tick = a8::XGetTickCount(); node_key_hash_[key] = gs; - node_sorted_list_.push_back(&node_key_hash_[key]); + AddNodeToSortedNodes(&node_key_hash_[key]); RearrangeNode(); } @@ -130,6 +138,7 @@ void GSMgr::___GSList(f8::JsonHttpRequest* request) node->SetVal("ip", pair.second.ip); node->SetVal("port", pair.second.port); node->SetVal("servicing", pair.second.servicing); + node->SetVal("channel", pair.second.channel); node_list->Push(*node); delete node; } @@ -142,17 +151,20 @@ void GSMgr::___GSList(f8::JsonHttpRequest* request) { a8::MutableXObject* node_list = a8::MutableXObject::NewArray(); - for (GSNode* gs_node : node_sorted_list_) { - a8::MutableXObject* node = a8::MutableXObject::NewObject(); - node->SetVal("node_id", gs_node->node_id); - node->SetVal("instance_id", gs_node->instance_id); - node->SetVal("room_num", gs_node->room_num); - node->SetVal("online_num", gs_node->online_num); - node->SetVal("ip", gs_node->ip); - node->SetVal("port", gs_node->port); - node->SetVal("servicing", gs_node->servicing); - node_list->Push(*node); - delete node; + for (auto& pair : sorted_node_hash_) { + for (GSNode* gs_node : pair.second) { + a8::MutableXObject* node = a8::MutableXObject::NewObject(); + node->SetVal("node_id", gs_node->node_id); + node->SetVal("instance_id", gs_node->instance_id); + node->SetVal("room_num", gs_node->room_num); + node->SetVal("online_num", gs_node->online_num); + node->SetVal("ip", gs_node->ip); + node->SetVal("port", gs_node->port); + node->SetVal("servicing", gs_node->servicing); + node->SetVal("channel", gs_node->channel); + node_list->Push(*node); + delete node; + } } request->resp_xobj->SetVal("errcode", 0); @@ -176,20 +188,8 @@ GSNode* GSMgr::GetNodeByNodeKey(const std::string& node_key) GSNode* GSMgr::AllocNode(int channel) { - std::vector* sorted_nodes = &node_sorted_list_; - std::vector spec_nodes; - if (App::Instance()->IsSeparateChannel(channel)) { - for (GSNode* node : node_sorted_list_) { - if (spec_nodes.size() >= 2) { - break; - } - if (node->channel == channel) { - spec_nodes.push_back(node); - } - } - sorted_nodes = &spec_nodes; - } - if (!sorted_nodes->empty()) { + std::vector* sorted_nodes = GetSortedNodesByChannel(channel); + if (sorted_nodes && !sorted_nodes->empty()) { size_t rnd = std::min((size_t)2, sorted_nodes->size()); int idx = rand() % rnd; while (idx >= 0) { @@ -200,9 +200,9 @@ GSNode* GSMgr::AllocNode(int channel) } } a8::UdpLog::Instance()->Warning - ("节点分配失败 node_sorted_list.size:%d node_list.size:%d sorted_node.size:%d channel:%d", + ("节点分配失败 sorted_node_hashlist.size:%d node_list.size:%d sorted_node.size:%d channel:%d", { - node_sorted_list_.size(), + sorted_node_hash_.size(), node_key_hash_.size(), sorted_nodes->size(), channel @@ -212,33 +212,35 @@ GSNode* GSMgr::AllocNode(int channel) void GSMgr::RearrangeNode() { - std::sort(node_sorted_list_.begin(), node_sorted_list_.end(), - [] (const GSNode* a, const GSNode* b) - { - if (a->servicing && b->servicing) { - if (a->online_num < b->online_num) { + for (auto& pair : sorted_node_hash_) { + std::sort(pair.second.begin(), pair.second.end(), + [] (const GSNode* a, const GSNode* b) + { + if (a->servicing && b->servicing) { + if (a->online_num < b->online_num) { + return true; + } + if (a->online_num > b->online_num) { + return false; + } + if (a->room_num < b->room_num) { + return true; + } + if (a->room_num > b->room_num) { + return false; + } + return a->node_idx > b->node_idx; + } + if (a->servicing) { return true; } - if (a->online_num > b->online_num) { - return false; - } - if (a->room_num < b->room_num) { - return true; - } - if (a->room_num > b->room_num) { + if (b->servicing) { return false; } return a->node_idx > b->node_idx; } - if (a->servicing) { - return true; - } - if (b->servicing) { - return false; - } - return a->node_idx > b->node_idx; - } - ); + ); + } } void GSMgr::ClearTimeOutNode() @@ -250,14 +252,7 @@ void GSMgr::ClearTimeOutNode() } } for (GSNode* node : time_out_nodes) { - { - for (size_t i = 0; i < node_sorted_list_.size(); ++i) { - if (node_sorted_list_[i] == node) { - node_sorted_list_.erase(node_sorted_list_.begin() + i); - break; - } - } - } + RemoveNodeRomSortedNodes(node); { std::vector deleted_teams; for (auto& pair : team_hash_) { @@ -273,3 +268,42 @@ void GSMgr::ClearTimeOutNode() } RearrangeNode(); } + +void GSMgr::AddNodeToSortedNodes(GSNode* node) +{ + auto itr = sorted_node_hash_.find(node->channel); + if (itr != sorted_node_hash_.end()) { + itr->second.push_back(node); + } else { + sorted_node_hash_[node->channel] = std::vector({node}); + } +} + +void GSMgr::RemoveNodeRomSortedNodes(GSNode* node) +{ + for (auto& pair : sorted_node_hash_) { + std::vector& node_list = pair.second; + for (size_t i = 0; i < node_list.size(); ++i) { + if (node_list[i] == node) { + node_list.erase(node_list.begin() + i); + break; + } + } + } +} + +std::vector* GSMgr::GetSortedNodesByChannel(int channel) +{ + auto itr = sorted_node_hash_.find(channel); + if (itr != sorted_node_hash_.end()) { + return &itr->second; + } else { + return nullptr; + } +} + +void GSMgr::OnChannelChange(GSNode* node) +{ + RemoveNodeRomSortedNodes(node); + AddNodeToSortedNodes(node); +} diff --git a/server/masterserver/gsmgr.h b/server/masterserver/gsmgr.h index f76d752..2a3bac6 100644 --- a/server/masterserver/gsmgr.h +++ b/server/masterserver/gsmgr.h @@ -44,10 +44,14 @@ class GSMgr : public a8::Singleton GSNode* AllocNode(int channel); void RearrangeNode(); void ClearTimeOutNode(); + void AddNodeToSortedNodes(GSNode* node); + void RemoveNodeRomSortedNodes(GSNode* node); + std::vector* GetSortedNodesByChannel(int channel); + void OnChannelChange(GSNode* node); private: std::map team_hash_; std::map node_key_hash_; - std::vector node_sorted_list_; + std::map> sorted_node_hash_; };