Fix: #293 Wrong keep-alive time set for IOCPServer

This commit is contained in:
yuanyuanxiang
2026-01-27 19:58:20 +01:00
parent d49c541ea2
commit e40cb4da92
5 changed files with 48 additions and 3 deletions

View File

@@ -58,6 +58,7 @@
#define TIMER_CHECK 1
#define TIMER_CLOSEWND 2
#define TIMER_CLEAR_BALLOON 3
#define TIMER_HEARTBEAT_CHECK 4
#define TODO_NOTICE MessageBoxA("This feature has not been implemented!\nPlease contact: 962914132@qq.com", "提示", MB_ICONINFORMATION);
#define TINY_DLL_NAME "TinyRun.dll"
#define FRPC_DLL_NAME "Frpc.dll"
@@ -1292,6 +1293,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
#else
SetTimer(TIMER_CHECK, max(1, tm) * 60 * 1000, NULL);
#endif
SetTimer(TIMER_HEARTBEAT_CHECK, 30 * 1000, NULL);
UPDATE_SPLASH(85, "正在启动FRP代理...");
m_hFRPThread = CreateThread(NULL, 0, StartFrpClient, this, NULL, NULL);
@@ -1565,10 +1567,39 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent)
nid.szInfoTitle[0] = '\0';
Shell_NotifyIcon(NIM_MODIFY, &nid);
}
if (nIDEvent == TIMER_HEARTBEAT_CHECK && m_settings.ReportInterval > 0) {
CheckHeartbeat();
}
CDialogEx::OnTimer(nIDEvent);
}
void CMy2015RemoteDlg::CheckHeartbeat() {
CLock lock(m_cs);
auto now = time(0);
int HEARTBEAT_TIMEOUT = max(30, m_settings.ReportInterval * 3);
for (auto it = m_HostList.begin(); it != m_HostList.end(); ) {
context* ContextObject = *it;
if (now - ContextObject->GetLastHeartbeat() > HEARTBEAT_TIMEOUT) {
auto host = ContextObject->GetAdditionalData(RES_CLIENT_PUBIP);
host = host.IsEmpty() ? std::to_string(ContextObject->GetClientID()).c_str() : host;
Mprintf("Client %s[%llu] heartbeat timeout!!! \n", host, ContextObject->GetClientID());
PostMessageA(WM_SHOWNOTIFY, (WPARAM)new CharMsg("主机掉线"),
(LPARAM)new CharMsg("主机长时间无心跳: " + host));
it = m_HostList.erase(it);
ContextObject->CancelIO();
for (int i = 0, n = m_CList_Online.GetItemCount(); i < n; i++) {
auto lParam = m_CList_Online.GetItemData(i);
if (lParam == (LPARAM)ContextObject) {
m_CList_Online.DeleteItem(i);
break;
}
}
} else {
++it;
}
}
}
void CMy2015RemoteDlg::DeletePopupWindow(BOOL bForce)
{
@@ -2907,6 +2938,7 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
BYTE buf[sizeof(HeartbeatACK) + 1] = { CMD_HEARTBEAT_ACK};
memcpy(buf + 1, &ack, sizeof(HeartbeatACK));
ctx->Send2Client(buf, sizeof(buf));
ctx->SetLastHeartbeat(time(0));
}
CLock L(m_cs);
@@ -2918,6 +2950,7 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
if (hb.Ping > 0)
m_CList_Online.SetItemText(i, ONLINELIST_PING, std::to_string(hb.Ping).c_str());
m_CList_Online.SetItemText(i, ONLINELIST_VIDEO, hb.HasSoftware ? "" : "");
id->SetLastHeartbeat(time(0));
return;
}
}

View File

@@ -159,6 +159,7 @@ public:
std::string m_selectedGroup;
void LoadListData(const std::string& group);
void DeletePopupWindow(BOOL bForce = FALSE);
void CheckHeartbeat();
context* FindHost(int port);
context* FindHost(uint64_t id);

View File

@@ -700,7 +700,7 @@ void IOCPServer::OnAccept()
//设置套接字的选项卡 Set KeepAlive 开启保活机制 SO_KEEPALIVE
//保持连接检测对方主机是否崩溃如果2小时内在此套接口的任一方向都没
//有数据交换TCP就自动给对方 发一个保持存活
m_ulKeepLiveTime = 3;
m_ulKeepLiveTime = 1000 * 60 * 3;
const BOOL bKeepAlive = TRUE;
setsockopt(ContextObject->sClientSocket,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));

View File

@@ -339,6 +339,12 @@ public:
Zcctx = nullptr;
}
}
virtual void SetLastHeartbeat(uint64_t time) override {
LastHeartbeatTime = time;
}
virtual uint64_t GetLastHeartbeat() override {
return LastHeartbeatTime;
}
CString sClientInfo[ONLINELIST_MAX];
CString additonalInfo[RES_MAX];
SOCKET sClientSocket;
@@ -361,7 +367,8 @@ public:
ikcpcb* kcp = nullptr; // 新增指向KCP会话
std::string GroupName; // 分组名称
CLock SendLock; // fix #214
time_t OnlineTime; // 上线时间
time_t OnlineTime = 0; // 上线时间
time_t LastHeartbeatTime = 0; // 最后心跳时间
// 预分配的解压缩缓冲区,避免频繁内存分配
PBYTE DecompressBuffer = nullptr;
@@ -483,6 +490,7 @@ public:
m_bProxyConnected = FALSE;
server = (Server*)svr;
OnlineTime = time(0);
LastHeartbeatTime = OnlineTime;
}
uint64_t GetAliveTime()const
{
@@ -564,7 +572,7 @@ public:
{
return ID;
}
void CancelIO()
void CancelIO() override
{
SAFE_CANCELIO(sClientSocket);
}

View File

@@ -39,6 +39,9 @@ public:
virtual FlagType GetFlagType() const = 0;
virtual std::string GetGroupName() const = 0;
virtual uint64_t GetAliveTime()const = 0;
virtual void SetLastHeartbeat(uint64_t time) = 0;
virtual uint64_t GetLastHeartbeat() = 0;
virtual void CancelIO() = 0;
public:
virtual ~context() {}
virtual void Destroy() {}