134 lines
4.8 KiB
C++
134 lines
4.8 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/openssl.h>
|
|
#include <a8/timer.h>
|
|
|
|
#include "cachemgr.h"
|
|
#include "app.h"
|
|
#include "jsondatamgr.h"
|
|
#include "typeconvert.h"
|
|
#include "svrmgr.h"
|
|
#include "IMListener.h"
|
|
|
|
void CacheMgr::Init()
|
|
{
|
|
INIT_LIST_HEAD(&friend_list_);
|
|
curr_entry_ = &friend_list_;
|
|
a8::Timer::Instance()->AddRepeatTimerAndAttach
|
|
(
|
|
1000 * 10,
|
|
a8::XParams(),
|
|
[] (const a8::XParams& param)
|
|
{
|
|
CacheMgr::Instance()->RemoveTimeoutFriend();
|
|
},
|
|
&timer_attacher_.timer_list_
|
|
);
|
|
}
|
|
|
|
void CacheMgr::UnInit()
|
|
{
|
|
timer_attacher_.ClearTimerList();
|
|
}
|
|
|
|
void CacheMgr::_SS_IM_UserOnline(f8::MsgHdr& hdr, const ss::SS_IM_UserOnline& msg)
|
|
{
|
|
SvrNode* svr_node = SvrMgr::Instance()->GetNodeBySocket(hdr.socket_handle);
|
|
if (svr_node) {
|
|
for (auto& user_info : msg.user_infos()) {
|
|
unsigned int crc32_code = a8::openssl::Crc32
|
|
(
|
|
(unsigned char*)user_info.base_data().account_id().data(),
|
|
user_info.base_data().account_id().size()
|
|
);
|
|
int instance_id = crc32_code % JsonDataMgr::Instance()->GetMasterSvrNum() + 1;
|
|
if (App::Instance()->instance_id == instance_id) {
|
|
Friend* friend_data = GetFriendData(user_info.base_data().account_id());
|
|
if (!friend_data) {
|
|
friend_data = new Friend();
|
|
list_add_tail(&friend_data->human_entry, &svr_node->human_list);
|
|
list_add_tail(&friend_data->cache_entry, &friend_list_);
|
|
friend_data->svr_node = svr_node;
|
|
friend_hash_[user_info.base_data().account_id()] = friend_data;
|
|
} else {
|
|
if (friend_data->svr_node != svr_node) {
|
|
if (!list_empty(&friend_data->human_entry)) {
|
|
list_del_init(&friend_data->human_entry);
|
|
}
|
|
list_add_tail(&friend_data->human_entry, &svr_node->human_list);
|
|
friend_data->svr_node = svr_node;
|
|
}
|
|
}
|
|
friend_data->last_active_tick = a8::XGetTickCount();
|
|
TypeConvert::Convert(user_info.base_data(), friend_data->base_data);
|
|
TypeConvert::Convert(user_info.temp_custom_data(), friend_data->temp_custom_data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CacheMgr::_SS_IM_UserOffline(f8::MsgHdr& hdr, const ss::SS_IM_UserOffline& msg)
|
|
{
|
|
SvrNode* svr_node = SvrMgr::Instance()->GetNodeBySocket(hdr.socket_handle);
|
|
if (svr_node) {
|
|
for (const std::string& account_id : msg.account_ids()) {
|
|
Friend* friend_data = GetFriendData(account_id);
|
|
if (friend_data) {
|
|
friend_data->base_data.online = false;
|
|
if (!list_empty(&friend_data->human_entry)) {
|
|
list_del_init(&friend_data->human_entry);
|
|
}
|
|
friend_data->svr_node = nullptr;
|
|
friend_data->last_active_tick = a8::XGetTickCount();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CacheMgr::_SS_IM_PullUserList(f8::MsgHdr& hdr, const ss::SS_IM_PullUserList& msg)
|
|
{
|
|
ss::SS_MS_PushUserList respmsg;
|
|
for (const std::string& account_id : msg.account_ids()) {
|
|
Friend* friend_data = GetFriendData(account_id);
|
|
if (friend_data) {
|
|
auto p = respmsg.add_user_infos();
|
|
TypeConvert::Convert(friend_data->base_data, *p->mutable_base_data());
|
|
TypeConvert::Convert(friend_data->temp_custom_data, *p->mutable_temp_custom_data());
|
|
}
|
|
}
|
|
IMListener::Instance()->SendMsg(hdr.socket_handle, respmsg);
|
|
}
|
|
|
|
Friend* CacheMgr::GetFriendData(const std::string& account_id)
|
|
{
|
|
auto itr = friend_hash_.find(account_id);
|
|
return itr != friend_hash_.end() ? itr->second : nullptr;
|
|
}
|
|
|
|
void CacheMgr::RemoveTimeoutFriend()
|
|
{
|
|
if (friend_hash_.size() < 10000 * 50) {
|
|
return;
|
|
}
|
|
int num = 0;
|
|
long long tick = a8::XGetTickCount();
|
|
while (!list_is_last(curr_entry_, &friend_list_) && num++ < 1000) {
|
|
list_head* p = curr_entry_;
|
|
curr_entry_ = curr_entry_->next;
|
|
|
|
Friend* friend_data = list_entry(p, Friend, cache_entry);
|
|
long long inactive_tick = tick - friend_data->last_active_tick;
|
|
if ((friend_data->base_data.online && inactive_tick > 1000 * 3600 * 24 * 2) ||
|
|
(!friend_data->base_data.online && inactive_tick > 1000 * 3600 * 24)) {
|
|
if (!list_empty(&friend_data->human_entry)) {
|
|
list_del_init(&friend_data->human_entry);
|
|
}
|
|
list_del_init(&friend_data->cache_entry);
|
|
friend_hash_.erase(friend_data->base_data.account_id);
|
|
}
|
|
}
|
|
if (list_is_last(curr_entry_, &friend_list_)) {
|
|
curr_entry_ = &friend_list_;
|
|
}
|
|
}
|