From 17f83edce4d535404efd2e04a3cef6e63f93b5cd Mon Sep 17 00:00:00 2001 From: cyrille Date: Tue, 15 Sep 2026 12:05:06 -0400 Subject: [PATCH] proxy: add Huawei (HMS) push type Route push notifications to Huawei devices, which have no Google Play Services and therefore cannot receive FCM. gorush, already used as the push relay, supports HMS natively as platform 3. HMS takes its payload as a serialized JSON string in "huawei_data" and carries its own ttl/priority fields, so it needs its own branch rather than the generic "data" object used for FCM and APNs. The enum value is appended last: MSGPACK_ADD_ENUM serializes it as an integer, so reordering would break compatibility with deployed proxies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- include/opendht/dht_proxy_server.h | 6 +++++- src/dht_proxy_server.cpp | 26 ++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/opendht/dht_proxy_server.h b/include/opendht/dht_proxy_server.h index a957b091..fc0f5816 100644 --- a/include/opendht/dht_proxy_server.h +++ b/include/opendht/dht_proxy_server.h @@ -19,7 +19,9 @@ #include namespace dht { -enum class PushType { None = 0, Android, iOS, UnifiedPush }; +// Appended only: the values are serialized as integers by MSGPACK_ADD_ENUM, +// so reordering would break compatibility with deployed proxies. +enum class PushType { None = 0, Android, iOS, UnifiedPush, Huawei }; } MSGPACK_ADD_ENUM(dht::PushType) @@ -132,6 +134,7 @@ public: PushStats androidPush; PushStats iosPush; PushStats unifiedPush; + PushStats huaweiPush; /** Average requests per second */ double requestRate {0}; @@ -397,6 +400,7 @@ private: PushStats androidPush_; PushStats iosPush_; PushStats unifiedPush_; + PushStats huaweiPush_; // Thread-safe access to listeners map. std::mutex lockListener_; diff --git a/src/dht_proxy_server.cpp b/src/dht_proxy_server.cpp index d96cb5dc..c6d2afa3 100644 --- a/src/dht_proxy_server.cpp +++ b/src/dht_proxy_server.cpp @@ -97,7 +97,7 @@ std::string DhtProxyServer::ServerStats::toString() const { auto ret = fmt::format("Listens: {}, Puts: {}, PushListeners: {}\n" - "Push requests in the last {}: [Android: {}], [iOS: {}], [Unified: {}]\n" + "Push requests in the last {}: [Android: {}], [iOS: {}], [Unified: {}], [Huawei: {}]\n" "Requests: {} per second.", listenCount, putCount, @@ -106,6 +106,7 @@ DhtProxyServer::ServerStats::toString() const androidPush.toString(), iosPush.toString(), unifiedPush.toString(), + huaweiPush.toString(), requestRate); if (nodeInfo) { auto& ipv4 = nodeInfo->ipv4; @@ -131,6 +132,7 @@ DhtProxyServer::ServerStats::toJson() const result["androidPush"] = androidPush.toJson(); result["iosPush"] = iosPush.toJson(); result["unifiedPush"] = unifiedPush.toJson(); + result["huaweiPush"] = huaweiPush.toJson(); result["requestRate"] = requestRate; if (nodeInfo) result["nodeInfo"] = nodeInfo->toJson(); @@ -639,6 +641,7 @@ DhtProxyServer::updateStats(std::shared_ptr info) const stats.androidPush = androidPush_; stats.iosPush = iosPush_; stats.unifiedPush = unifiedPush_; + stats.huaweiPush = huaweiPush_; } #endif stats.serverStartTime = serverStartTime_; @@ -864,6 +867,8 @@ DhtProxyServer::getTypeFromString(const std::string& type) return PushType::iOS; else if (type == "unifiedpush") return PushType::UnifiedPush; + else if (type == "huawei") + return PushType::Huawei; return PushType::None; } @@ -1275,15 +1280,25 @@ DhtProxyServer::sendPushNotification( Json::Value tokens(Json::arrayValue); tokens[0] = token; notification["tokens"] = std::move(tokens); - notification["platform"] = type == PushType::Android ? 2 : 1; - notification["data"] = std::move(json); + // gorush platform codes: 1 = iOS (APNs), 2 = Android (FCM), 3 = Huawei (HMS) + notification["platform"] = type == PushType::Android ? 2 + : type == PushType::Huawei ? 3 + : 1; auto priority = highPriority ? "high" : "normal"; - if (type == PushType::Android) { + if (type == PushType::Huawei) { + // HMS carries the payload as a serialized JSON string in its own field: + // the generic "data" object is ignored for this platform by gorush. + notification["huawei_data"] = Json::writeString(jsonBuilder_, json); + notification["huawei_ttl"] = "86400s"; // time to live = 24 hours + notification["priority"] = priority; + } else if (type == PushType::Android) { + notification["data"] = std::move(json); Json::Value androidConfig(Json::objectValue); androidConfig["priority"] = priority; androidConfig["ttl"] = "86400s"; // time to live = 24 hours notification["android"] = std::move(androidConfig); } else { + notification["data"] = std::move(json); notification["priority"] = priority; const auto expiration = std::chrono::system_clock::now() + std::chrono::hours(24); uint32_t exp = std::chrono::duration_cast(expiration.time_since_epoch()).count(); @@ -1336,6 +1351,9 @@ DhtProxyServer::sendPushNotification( case PushType::UnifiedPush: unifiedPush_.increment(highPriority); break; + case PushType::Huawei: + huaweiPush_.increment(highPriority); + break; default: break; }