业务场景:
适用于后端服务开发:
这一次你需要开发一个服务器,有若干设备连接到你,常见的如TCP数据服务器等;
期间,设备定时60秒向你发送心跳,你需要维持在线状态,同时在3个周期(即180秒内没有收到心跳)认为设备离线。
分享简单做法(依赖时间轴)
std::mutex m_onlineMutex;
std::map<std::string, time_t> m_mapOnline;
void UpdateOnlineState(std::string& ip)
{
time_t m_curtime;
time(&m_curtime);
std::lock_guard<std::mutex> lk(m_onlineMutex);
auto it = m_mapOnline.find(ip);
if (it == m_mapOnline.end())
{
m_mapOnline.insert(std::pair<string, time_t>(ip, m_curtime));
}
else
{
it->second = m_curtime;
}
}
bool GetofflineDevices(std::vector<std::string>& ips)
{
time_t m_devtime;
time_t m_curtime;
time(&m_curtime);
std::lock_guard<std::mutex> lk(m_onlineMutex);
for (auto& it : m_mapOnline)
{
m_devtime = it.second;
if (abs(m_curtime - m_devtime) >= 3 * 60) //大于3分钟
{
ips.push_back(it.first);
}
}
for (auto it = ips.begin(); it != ips.end(); it++)
{
m_mapOnline.erase((*it));
}
return true;
}
应用时:接收到心跳时,调用UpdateOnlineState更新在线时长;
在异步线程中,调用GetofflineDevices获取离线设备;
更可靠的做法(按程序启动时间开始记录时间)
- 自定义时间轴
需要自行实现定时器线程。功能代替time函数(不获取系统时间);该定时器线程产生程序启动后运行的时长,可以用秒记录。
- 使用系统API
如果使用系统api。例如Windows的GetTickCount;