在後臺 服務器處理客戶端發過來的數據時,由於通信網絡傳輸 較差,實際收到了客戶端的數據並進行了處理,給出了迴應,但客戶端由於網絡原因判斷爲該條消息未發送成功,而重發。則服務器程序必須做出去重。
觀察 實際解析到的消息結構體 如下
typedef struct
{
time_t m_c_time,
string m_localid,
string m_buddyid,
string m_msg,
}msg_info;
time 對多個msg_info實際並不唯一,所以 要根據 time_t m_c_time,
string m_localid, string m_buddyid,這三個參數生成一個md5值作爲唯一的map索引(因爲要求快速響應速度)
所以 將生成的md5值轉化爲string,作爲map的key
將 time_t作爲時間標記,作爲 map的value
具體代碼如下
static std::map<string,time_t> s_chat_indentity;
string md5Index;
char md5buf[33];
bzero(md5buf,33);
int nLen =0;
for(int i =0;i< 16;i++)
{
nLen += sprintf(md5buf+nLen,"%x",0xff&(md5Str[i]));// no "%02x"
}
//實際生成的md5值以16進制打印出來的字符串 包含有0,所以不能用 "%02x",補齊
md5Index = md5buf;
time_t curtime;
time(&curtime);
std::map<string,time_t>::iterator it = s_chat_identify.find(md5Index);
if(it != s_chat_identify.end())
{
s_chat_identify[md5Index]= curtime;
//更新 md5 對應記錄的最後一次出現的時間
return false;
}
if(s_chat_identify.size() >= MAX_MAP_COUNT)
{
for(map<string,time_t>::iterator it = s_chat_identify.begin();it!= s_chat_identify.end();)
{
if(curtime - it->second > MAX_TIME_DIF)
{
s_chat_identify.erase(it++);
//對map的時間值進行排序耗時太大,所以改 選擇 找出 時間差超過限制的老記錄刪除之
//另外 map的迭代器刪除和vector的順序存儲容器不一樣
}
else
{
++it;
}
}
}
if(s_chat_identify.size() >= MAX_MAP_COUNT_LIMIT)
{
s_chat_identify.erase(s_chat_identify.begin());
//超過map的最大限,則選擇刪除 最開始的
PRINT_LOG(__FILE__,__LINE__,ERROR_LEVEL,-1,"random del first record, map size is too larger : %d", s_chat_identify.size());
}
s_chat_identify.insert(pair<string, time_t>(md5Index, curtime));