修正业务逻辑,vid以neardi侧为准,orin不再管理vid

This commit is contained in:
cxh 2026-01-05 14:46:19 +08:00
parent e12b5a95e7
commit 8c2c5cb0ab
3 changed files with 16 additions and 82 deletions

View File

@ -76,9 +76,6 @@ struct AppConfig
std::vector<Camera> cameras; std::vector<Camera> cameras;
MQTTConfig mqtt; MQTTConfig mqtt;
// ⭐ 运行期从 orin 获取的 VID优先生效
std::string runtime_vid;
static AppConfig load_from_file(const std::string& filepath) static AppConfig load_from_file(const std::string& filepath)
{ {
AppConfig cfg; AppConfig cfg;

View File

@ -19,47 +19,6 @@ std::atomic<bool> g_streaming{false};
std::string g_dispatch_id; std::string g_dispatch_id;
std::mutex g_dispatch_id_mutex; std::mutex g_dispatch_id_mutex;
static std::atomic<bool> g_mqtt_activated{false};
static std::string g_last_vid;
static VehicleMQTTTopics g_prev_topics;
static bool try_activate_mqtt()
{
if (g_app_config.runtime_vid.empty()) return false;
if (!mqtt_client || !mqtt_client->isConnected()) return false;
// 如果已激活且 VID 未变化,什么都不做
if (g_mqtt_activated.load() && g_last_vid == g_app_config.runtime_vid) return true;
// ---------- 1. 如果是 VID 变化,先取消旧订阅 ----------
if (g_mqtt_activated.load())
{
LOG_INFO("[MQTT] VID changed, unsubscribe old topics: " + g_last_vid);
mqtt_client->unsubscribe(g_prev_topics.video_down);
mqtt_client->unsubscribe(g_prev_topics.record_query);
mqtt_client->unsubscribe(g_prev_topics.record_play);
mqtt_client->unsubscribe(g_prev_topics.vehicle_ctrl);
mqtt_client->unsubscribe(g_prev_topics.heartbeat_up);
}
// ---------- 2. 切换到新 VID ----------
g_app_config.mqtt.topics.fill_with_veh_id(g_app_config.runtime_vid);
g_prev_topics = g_app_config.mqtt.topics;
g_last_vid = g_app_config.runtime_vid;
LOG_INFO("[MQTT] Activated with VID=" + g_last_vid);
// ---------- 3. 订阅新 topic ----------
mqtt_client->subscribe(g_app_config.mqtt.topics.video_down);
mqtt_client->subscribe(g_app_config.mqtt.topics.record_query);
mqtt_client->subscribe(g_app_config.mqtt.topics.record_play);
mqtt_client->subscribe(g_app_config.mqtt.topics.vehicle_ctrl);
g_mqtt_activated.store(true);
return true;
}
static void send_heartbeat() static void send_heartbeat()
{ {
if (!mqtt_client || !mqtt_client->isConnected()) return; if (!mqtt_client || !mqtt_client->isConnected()) return;
@ -110,7 +69,14 @@ static void send_heartbeat()
static void on_mqtt_connected() static void on_mqtt_connected()
{ {
LOG_INFO("[MQTT] Connected to broker: " + g_app_config.mqtt.server_ip); LOG_INFO("[MQTT] Connected to broker: " + g_app_config.mqtt.server_ip);
g_mqtt_activated.store(false); // 重连后需要重新激活
// 一次性订阅VID 来自配置文件,永远不变)
mqtt_client->subscribe(g_app_config.mqtt.topics.video_down);
mqtt_client->subscribe(g_app_config.mqtt.topics.record_query);
mqtt_client->subscribe(g_app_config.mqtt.topics.record_play);
mqtt_client->subscribe(g_app_config.mqtt.topics.vehicle_ctrl);
LOG_INFO("[MQTT] Subscribed all topics for VID=" + g_app_config.mqtt.vehicle_id);
} }
static void on_mqtt_disconnected() { LOG_WARN("[MQTT] Disconnected from broker: " + g_app_config.mqtt.server_ip); } static void on_mqtt_disconnected() { LOG_WARN("[MQTT] Disconnected from broker: " + g_app_config.mqtt.server_ip); }
@ -401,12 +367,8 @@ void mqtt_client_thread_func()
// 主循环:心跳 // 主循环:心跳
while (g_running && mqtt_client->isConnected()) while (g_running && mqtt_client->isConnected())
{ {
try_activate_mqtt(); // VID 到来时触发订阅 send_heartbeat();
if (g_mqtt_activated.load())
{
send_heartbeat();
}
auto sleep_time = heartbeat_interval; auto sleep_time = heartbeat_interval;
while (sleep_time.count() > 0 && g_running && mqtt_client->isConnected()) while (sleep_time.count() > 0 && g_running && mqtt_client->isConnected())
{ {

View File

@ -65,44 +65,19 @@ void start_http_server(int port)
return; return;
} }
// ---------- 2. 解析请求体(尝试获取 VID ---------- // ---------- 2. 请求体当前不承载身份(忽略即可) ----------
std::string vid;
if (!req.body.empty()) if (!req.body.empty())
{ {
try LOG_INFO("[http] register payload ignored");
{
auto jreq = nlohmann::json::parse(req.body);
if (jreq.contains("vid") && jreq["vid"].is_string())
{
vid = jreq["vid"].get<std::string>();
LOG_INFO("[http] register vid = " + vid);
// ⭐ 运行期 VID只记录不判断
g_app_config.runtime_vid = vid;
}
}
catch (const std::exception& e)
{
LOG_WARN(std::string("[http] invalid json payload: ") + e.what());
}
}
else
{
LOG_WARN("[http] empty register payload");
} }
// ---------- 3. 返回 B 的身份 ---------- // ---------- 3. 返回 B 的身份(唯一事实源) ----------
std::string imei = get_imei();
nlohmann::json jres; nlohmann::json jres;
jres["ok"] = true; jres["ok"] = true;
jres["server"] = {{"device_type", "neardi"}, {"imei", imei}, {"fw", "b-v2.1.0"}}; jres["device"] = {{"device_type", "neardi"},
{"imei", get_imei()},
// 可选:把 vid 回显(方便 A / 调试) {"vid", g_app_config.mqtt.vehicle_id},
if (!vid.empty()) {"fw", "b-v2.1.0"}};
{
jres["peer"] = {{"vid", vid}};
}
res.set_content(jres.dump(), "application/json"); res.set_content(jres.dump(), "application/json");
}); });