Fix: skip wasted geo-IP lookup blocking the host double-click tooltip
The online-host double-click handler called IPConverter::GetGeoLocation on the UI thread before showing the floating tooltip, even when no local IP database (QQWry/ip2region) was loaded. In that default configuration the result is never displayed, yet the call issues up to three synchronous HTTP requests (5s timeout each), delaying the tooltip by a network round trip or worse. Only run the lookup when a local database is actually loaded, and memoize successful results per IP in a process-wide cache inside GetGeoLocation so the remaining call sites (license activity, host-login fallback) do not re-query the same IP. The cache uses function-local statics rather than class members to keep IPConverter's layout unchanged and stay ABI-compatible with the precompiled PrivateDesktop_Lib.lib QQWry/Ip2Region subclasses. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
76decec0fe
commit
d118558eda
2 files changed
+26
-3
No files matched your search
+21
-1
@@ -4,6 +4,8 @@
|
|||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <WinInet.h>
|
#include <WinInet.h>
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "jsoncpp/json.h"
|
#include "jsoncpp/json.h"
|
||||||
|
|
||||||
@@ -200,6 +202,18 @@ public:
|
|||||||
{
|
{
|
||||||
if (IP.empty()) return "";
|
if (IP.empty()) return "";
|
||||||
|
|
||||||
|
// 进程级缓存(函数局部 static)。用局部 static 而非类成员,是为了不改动
|
||||||
|
// IPConverter 的类布局/尺寸——QQWry/Ip2Region 派生类来自预编译的
|
||||||
|
// PrivateDesktop_Lib.lib,改成员会与其产生 ABI 尺寸差异。
|
||||||
|
static std::map<std::string, std::string> geoCaches;
|
||||||
|
static std::mutex geoMutex;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(geoMutex);
|
||||||
|
auto it = geoCaches.find(IP);
|
||||||
|
if (it != geoCaches.end())
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ip = IP;
|
std::string ip = IP;
|
||||||
if (isLocalIP(ip)) {
|
if (isLocalIP(ip)) {
|
||||||
ip = getPublicIP();
|
ip = getPublicIP();
|
||||||
@@ -249,7 +263,13 @@ public:
|
|||||||
InternetCloseHandle(hInternet);
|
InternetCloseHandle(hInternet);
|
||||||
|
|
||||||
if (location.empty() && IsPrivateIP(ip)) {
|
if (location.empty() && IsPrivateIP(ip)) {
|
||||||
return "Local Area Network";
|
location = "Local Area Network";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只缓存成功结果;失败不缓存,允许下次重试。
|
||||||
|
if (!location.empty()) {
|
||||||
|
std::lock_guard<std::mutex> lk(geoMutex);
|
||||||
|
geoCaches[IP] = location;
|
||||||
}
|
}
|
||||||
return location;
|
return location;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8728,8 +8728,11 @@ void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult)
|
|||||||
res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], res[RES_RESOLUTION], startTime, expired.c_str(),
|
res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], res[RES_RESOLUTION], startTime, expired.c_str(),
|
||||||
res[RES_USERNAME], res[RES_ISADMIN] == "1" ? _L("[管理员]") : res[RES_ISADMIN].IsEmpty() ? "" : _L("[非管理员]"), GetElapsedTime(startTime),
|
res[RES_USERNAME], res[RES_ISADMIN] == "1" ? _L("[管理员]") : res[RES_ISADMIN].IsEmpty() ? "" : _L("[非管理员]"), GetElapsedTime(startTime),
|
||||||
ctx->GetProtocol().c_str(), ctx->GetServerPort(), typMap[type].c_str(), ctx->GetMasterID().c_str(), res[RES_CLIENT_ID]);
|
ctx->GetProtocol().c_str(), ctx->GetServerPort(), typMap[type].c_str(), ctx->GetMasterID().c_str(), res[RES_CLIENT_ID]);
|
||||||
std::string geo = res[RES_CLIENT_PUBIP].IsEmpty() ? "" : m_IPConverter->GetGeoLocation(res[RES_CLIENT_PUBIP].GetString());
|
// 地理信息只在加载了本地 IP 库(QQWry/ip2region)时才查询并展示。
|
||||||
if (m_HasLocDB) {
|
// 未装库时 m_IPConverter 是网络版 GetGeoLocation(同步外网 HTTP,可达数秒),
|
||||||
|
// 且结果不会被显示——跳过可消除双击浮窗的弹出延时。
|
||||||
|
if (m_HasLocDB && !res[RES_CLIENT_PUBIP].IsEmpty()) {
|
||||||
|
std::string geo = m_IPConverter->GetGeoLocation(res[RES_CLIENT_PUBIP].GetString());
|
||||||
CString qqwryLoc;
|
CString qqwryLoc;
|
||||||
qqwryLoc.FormatL("\r\n地理信息: %s", geo.c_str());
|
qqwryLoc.FormatL("\r\n地理信息: %s", geo.c_str());
|
||||||
strText += qqwryLoc;
|
strText += qqwryLoc;
|
||||||
|
|||||||
Reference in new issue
Block a user