Fix: Calculate RTT exclude server side UI queue delay time
This commit is contained in:
@@ -1632,10 +1632,13 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
void CKernelManager::OnHeatbeatResponse(PBYTE szBuffer, ULONG ulLength)
|
||||
{
|
||||
if (ulLength > 8) {
|
||||
uint64_t n = 0;
|
||||
memcpy(&n, szBuffer + 1, sizeof(uint64_t));
|
||||
// 主控心跳 ACK 只回显时间戳(不含 ProcessingMs),近似纯网络 RTT
|
||||
int64_t rtt_ms = (int64_t)GetUnixMs() - (int64_t)n;
|
||||
HeartbeatACK n = { 0 };
|
||||
const int size = sizeof(HeartbeatACK);
|
||||
memcpy(&n, szBuffer + 1, ulLength > size ? size : HeartbeatACK_OldSize);
|
||||
int64_t total_rtt_ms = (int64_t)GetUnixMs() - (int64_t)n.Time;
|
||||
int64_t rtt_ms = total_rtt_ms;
|
||||
if (n.ProcessingMs > 0 && (int64_t)n.ProcessingMs < total_rtt_ms)
|
||||
rtt_ms = total_rtt_ms - (int64_t)n.ProcessingMs;
|
||||
m_nNetPing.update_from_sample((double)rtt_ms);
|
||||
// 试用版反代理:RTT 入采样窗口。
|
||||
// 启停由下方根据 m_settings 控制;非试用模式下 RecordSample 内部直接 return。
|
||||
|
||||
@@ -398,15 +398,18 @@ int DataProcess(void* user, PBYTE szBuffer, ULONG ulLength)
|
||||
HeartbeatACK* ack = (HeartbeatACK*)(szBuffer + 1);
|
||||
uint64_t now = GetUnixMs();
|
||||
g_lastHeartbeatAckMs.store(now, std::memory_order_relaxed); // 喂应用层 ACK 看门狗
|
||||
double rtt_ms = (double)(now - ack->Time);
|
||||
g_rttEstimator.update_from_sample(rtt_ms);
|
||||
int64_t total_rtt_ms = (int64_t)now - (int64_t)ack->Time;
|
||||
int64_t rtt_ms = total_rtt_ms;
|
||||
if (ack->ProcessingMs > 0 && (int64_t)ack->ProcessingMs < total_rtt_ms)
|
||||
rtt_ms = total_rtt_ms - (int64_t)ack->ProcessingMs;
|
||||
g_rttEstimator.update_from_sample((double)rtt_ms);
|
||||
// 心跳节奏太密日志会刷屏;最多 60s 一行
|
||||
static time_t lastAckLog = 0;
|
||||
time_t now_s = time(nullptr);
|
||||
if (now_s - lastAckLog >= 60) {
|
||||
lastAckLog = now_s;
|
||||
Mprintf("** [%p] Heartbeat ACK: RTT=%.1fms, SRTT=%.1fms ***\n",
|
||||
user, rtt_ms, g_rttEstimator.srtt * 1000);
|
||||
user, (double)rtt_ms, g_rttEstimator.srtt * 1000);
|
||||
}
|
||||
}
|
||||
} else if (szBuffer[0] == CMD_MASTERSETTING) {
|
||||
|
||||
@@ -750,14 +750,17 @@ int DataProcess(void* user, PBYTE szBuffer, ULONG ulLength)
|
||||
if (ulLength >= 1 + sizeof(HeartbeatACK)) {
|
||||
HeartbeatACK* ack = (HeartbeatACK*)(szBuffer + 1);
|
||||
uint64_t now = GetUnixMs();
|
||||
double rtt_ms = (double)(now - ack->Time);
|
||||
g_rttEstimator.update_from_sample(rtt_ms);
|
||||
int64_t total_rtt_ms = (int64_t)now - (int64_t)ack->Time;
|
||||
int64_t rtt_ms = total_rtt_ms;
|
||||
if (ack->ProcessingMs > 0 && (int64_t)ack->ProcessingMs < total_rtt_ms)
|
||||
rtt_ms = total_rtt_ms - (int64_t)ack->ProcessingMs;
|
||||
g_rttEstimator.update_from_sample((double)rtt_ms);
|
||||
// Log at most once per minute
|
||||
static uint64_t lastLogTime = 0;
|
||||
if (now - lastLogTime >= 60000) {
|
||||
lastLogTime = now;
|
||||
Mprintf("** [%p] Heartbeat ACK: RTT=%.1fms, SRTT=%.1fms ***\n",
|
||||
user, rtt_ms, g_rttEstimator.srtt * 1000);
|
||||
user, (double)rtt_ms, g_rttEstimator.srtt * 1000);
|
||||
}
|
||||
}
|
||||
} else if (szBuffer[0] == CMD_MASTERSETTING) {
|
||||
|
||||
@@ -5715,6 +5715,7 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
|
||||
}
|
||||
case TOKEN_HEARTBEAT:
|
||||
case 137: // 心跳【L】
|
||||
ContextObject->HeartbeatRecvMs.store(GetUnixMs(), std::memory_order_relaxed);
|
||||
g_2015RemoteDlg->PostMessageA(WM_UPDATE_ACTIVEWND, 0, (LPARAM)ContextObject);
|
||||
break;
|
||||
case TOKEN_SCREEN_PREVIEW_RSP: {
|
||||
@@ -6488,10 +6489,9 @@ void CMy2015RemoteDlg::SendPendingRenewal(CONTEXT_OBJECT* ctx, const std::string
|
||||
|
||||
void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
|
||||
{
|
||||
// 记录本心跳的服务端处理开始时间,用于在 ACK 里回报 ProcessingMs。
|
||||
// 客户端会用 (now - hb.Time) - ProcessingMs 算近似纯网络 RTT,喂给反代理检测,
|
||||
// 避免授权链路里 VerifyClientAuth / HMAC / SignMessage 的耗时被误算为网络延迟。
|
||||
const uint64_t t_start_ms = GetUnixMs();
|
||||
// 用 IOCP 线程记录的收包时刻作为起点,排除 UI 消息队列等待时间,
|
||||
// 使 ProcessingMs 仅反映真实服务端处理耗时。
|
||||
const uint64_t t_start_ms = ctx->HeartbeatRecvMs.load(std::memory_order_relaxed);
|
||||
|
||||
auto clientID = ctx->GetClientID();
|
||||
auto host = FindHost(clientID);
|
||||
|
||||
@@ -392,6 +392,10 @@ public:
|
||||
// 仅作为标记供后续命令处理 / 未来收紧策略使用。
|
||||
std::atomic<bool> m_bAuthenticated{false};
|
||||
|
||||
// 心跳包到达 IOCP 线程的时刻(ms),用于精确计算 ProcessingMs,
|
||||
// 避免 UI 消息队列等待时间污染服务端耗时统计。
|
||||
std::atomic<uint64_t> HeartbeatRecvMs{0};
|
||||
|
||||
// 预分配的解压缩缓冲区,避免频繁内存分配
|
||||
PBYTE DecompressBuffer = nullptr;
|
||||
ULONG DecompressBufferSize = 0;
|
||||
|
||||
Reference in New Issue
Block a user