fix deadlock

This commit is contained in:
lnk
2025-09-23 21:00:24 +08:00
parent b976795573
commit e997c88d82
5 changed files with 125 additions and 142 deletions

View File

@@ -3036,6 +3036,13 @@ std::string extract_filename1(const std::string& path) {
return (pos != std::string::npos) ? path.substr(pos + 1) : path; return (pos != std::string::npos) ? path.substr(pos + 1) : path;
} }
// ★新增dirname返回“目录/”(保留末尾斜杠;若没有目录则返回空串)
static inline std::string dirname_with_slash(const std::string& path) {
size_t pos = path.find_last_of("/\\");
if (pos == std::string::npos) return std::string{};
return path.substr(0, pos + 1);
}
//发送匹配的所有录波文件 //发送匹配的所有录波文件
bool SendAllQvvrFiles(qvvr_file& qfile, std::string& out_wavepath) { bool SendAllQvvrFiles(qvvr_file& qfile, std::string& out_wavepath) {
std::vector<std::string> wavepaths; std::vector<std::string> wavepaths;
@@ -3043,7 +3050,7 @@ bool SendAllQvvrFiles(qvvr_file& qfile, std::string& out_wavepath) {
bool send_success = true; bool send_success = true;
for (const auto& file_localpath : qfile.file_download) { for (const auto& file_localpath : qfile.file_download) {
std::string file_cloudpath = "comtrade/" + file_localpath; std::string file_cloudpath = "comtrade/" + dirname_with_slash(file_localpath);
std::string wavepath_result; std::string wavepath_result;
// 发送本地文件到远端,返回 wavepath // 发送本地文件到远端,返回 wavepath
@@ -3100,7 +3107,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
<< " | terminal_id=" << terminal_id << std::endl; << " | terminal_id=" << terminal_id << std::endl;
//台账加锁 //台账加锁
std::lock_guard<std::mutex> lock(ledgermtx); std::unique_lock<std::mutex> lock(ledgermtx);
// 去除 mac 路径前缀,仅保留文件名 // 去除 mac 路径前缀,仅保留文件名
std::string filename = sanitize(extract_filename1(filename_with_mac)); std::string filename = sanitize(extract_filename1(filename_with_mac));
@@ -3211,6 +3218,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
std::cout << std::endl; std::cout << std::endl;
std::cout << "[update_qvvr_file_download] Downloaded files (file_download): "; std::cout << "[update_qvvr_file_download] Downloaded files (file_download): ";
for (const auto& fn : s_down) std::cout << fn << " "; for (const auto& fn : s_down) std::cout << fn << " ";
std::cout << std::endl;
// 检查 file_download 是否与 file_name 完全一致(集合相同) // 检查 file_download 是否与 file_name 完全一致(集合相同)
if (s_name == s_down) { if (s_name == s_down) {
@@ -3226,10 +3234,28 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) { if (compare_qvvr_and_file(fpath, monitor.qvvrevent.qvvrdata,matched)) {
qfile.is_pair = true; // 文件与事件匹配成功 qfile.is_pair = true; // 文件与事件匹配成功
// ★新增:上传前拷贝“将要上传的文件列表”,避免锁外用容器引用
std::vector<std::string> files_to_send(qfile.file_download.begin(),
qfile.file_download.end());
// ★新增:构造一个临时 qvvr_file仅用于上传不改动原结构
qvvr_file tmp_send;
tmp_send.file_download.assign(files_to_send.begin(), files_to_send.end());
// 发送所有文件(已下载完成) // 发送所有文件(已下载完成)
std::string wavepath; std::string wavepath;
// ★在解锁前,备份“签名”,用于回锁后定位同一个 qfile
std::set<std::string> sig_names(qfile.file_name.begin(), qfile.file_name.end());
std::set<std::string> sig_downs(qfile.file_download.begin(), qfile.file_download.end());
// ★修改:把上传与上送 JSON 放到“解锁区间”
lock.unlock(); // ★新增:提前解锁
if (SendAllQvvrFiles(qfile, wavepath)) { if (SendAllQvvrFiles(qfile, wavepath)) {
//文件发送成功后更新事件 //文件发送成功后更新事件
transfer_json_qvvr_data(terminal_id, transfer_json_qvvr_data(terminal_id,
logical_seq, logical_seq,
matched.QVVR_Amg, matched.QVVR_Amg,
@@ -3239,6 +3265,9 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
matched.phase, matched.phase,
wavepath); wavepath);
// ★新增:上传成功后再加锁,准备修改台账
lock.lock();
// 删除上传成功的文件 // 删除上传成功的文件
for (const auto& uploaded_file : qfile.file_download) { for (const auto& uploaded_file : qfile.file_download) {
if (std::remove(uploaded_file.c_str()) != 0) { if (std::remove(uploaded_file.c_str()) != 0) {
@@ -3248,8 +3277,20 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
} }
} }
// 清除已发送的暂态文件 // ★替换原来的 i<size 判断为:按签名查找当前容器里的那一条
monitor.qvvrevent.qvvrfile.erase(monitor.qvvrevent.qvvrfile.begin() + i); auto it_qf = std::find_if(monitor.qvvrevent.qvvrfile.begin(),
monitor.qvvrevent.qvvrfile.end(),
[&](const qvvr_file& x){
std::set<std::string> n(x.file_name.begin(), x.file_name.end());
std::set<std::string> d(x.file_download.begin(), x.file_download.end());
return n==sig_names && d==sig_downs;
});
if (it_qf != monitor.qvvrevent.qvvrfile.end()) {
monitor.qvvrevent.qvvrfile.erase(it_qf); // ✔ 删到同一条
} else {
std::cerr << "[Cleanup] qvvrfile changed; target group not found, skip erase\n";
}
//清除暂态事件 //清除暂态事件
auto it = std::find_if( auto it = std::find_if(
@@ -3264,6 +3305,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
} }
} }
else { else {
lock.lock(); // ★新增:失败时补回锁
std::cerr << "[update_qvvr_file_download] Failed to send qvvr files for logical_seq=" << logical_seq << std::endl; std::cerr << "[update_qvvr_file_download] Failed to send qvvr files for logical_seq=" << logical_seq << std::endl;
} }
} }
@@ -3277,7 +3319,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
else{ else{
std::cout << "qvvr file still imcomplete!!!" << std::endl; std::cout << "qvvr file still imcomplete!!!" << std::endl;
} }
lock.unlock();
return true; // 当前文件处理成功 return true; // 当前文件处理成功
} }
} }
@@ -3286,6 +3328,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac_in, const st
} }
} }
lock.unlock();
return false; // 未匹配到终端ID或逻辑序号对应的监测点 return false; // 未匹配到终端ID或逻辑序号对应的监测点
} }
@@ -3300,43 +3343,28 @@ std::string normalize_mac(const std::string &mac) {
return res; return res;
} }
//找到dev的mac
std::string get_mac_by_devid(const std::string &devid) {
std::lock_guard<std::mutex> lock(ledgermtx);
for (auto &dev : terminal_devlist) {
if (dev.terminal_id == devid) {
return normalize_mac(dev.addr_str); // 规范化后返回
}
}
return {}; // 没找到返回空串
}
////////////////////////////////////////////////////////////////////////////////////////目录信息发送接口函数 ////////////////////////////////////////////////////////////////////////////////////////目录信息发送接口函数
bool send_file_list(const std::string &dev_id, const std::vector<tag_dir_info> &FileList) { bool send_file_list(terminal_dev* dev, const std::vector<tag_dir_info>& FileList) {
// 找到对应 terminal_dev
std::lock_guard<std::mutex> lock(ledgermtx);
auto it = std::find_if(terminal_devlist.begin(), terminal_devlist.end(), if (!dev) {
[&](const terminal_dev &dev) { return dev.terminal_id == dev_id; }); std::cerr << "[send_file_list_locked] dev=nullptr\n";
if (it == terminal_devlist.end()) {
std::cerr << "[send_file_list] device not found: " << dev_id << std::endl;
return false; return false;
} }
terminal_dev &dev = *it;
// 判断 isbusy==1 且 busytype==READING_FILEMENU // 判断 isbusy==1 且 busytype==READING_FILEMENU
if (dev.isbusy != 1 || dev.busytype != static_cast<int>(DeviceState::READING_FILEMENU)) { if (dev->isbusy != 1 || dev->busytype != static_cast<int>(DeviceState::READING_FILEMENU)) {
std::cerr << "[send_file_list] device not in READING_FILEMENU state." << std::endl; std::cerr << "[send_file_list] device not in READING_FILEMENU state." << std::endl;
return false; return false;
} }
// 构造 JSON 报文 // 构造 JSON 报文
nlohmann::json j; nlohmann::json j;
j["guid"] = dev.guid; j["guid"] = dev->guid;
j["FrontIP"] = FRONT_IP; // 这里填你的前置机 IP j["FrontIP"] = FRONT_IP; // 这里填你的前置机 IP
j["Node"] = g_front_seg_index; // 节点号 j["Node"] = g_front_seg_index; // 节点号
j["Dev_mac"] = normalize_mac(dev.addr_str); // addr_str 存的是 MAC j["Dev_mac"] = normalize_mac(dev->addr_str); // addr_str 存的是 MAC
// 构造 DirInfo 数组 // 构造 DirInfo 数组
nlohmann::json dirArray = nlohmann::json::array(); nlohmann::json dirArray = nlohmann::json::array();
@@ -3374,12 +3402,12 @@ bool send_file_list(const std::string &dev_id, const std::vector<tag_dir_info> &
std::cout << "[send_reply_to_cloud] queued: " << j.dump() << std::endl; std::cout << "[send_reply_to_cloud] queued: " << j.dump() << std::endl;
//发送后清除guid和标志 //发送后清除guid和标志
if (dev.isbusy > 0) { if (dev->isbusy > 0) {
dev.isbusy--; dev->isbusy--;
} }
if(dev.isbusy == 0){ if(dev->isbusy == 0){
dev.guid.clear(); dev->guid.clear();
dev.busytype = 0; dev->busytype = 0;
} }
return true; return true;
@@ -3432,7 +3460,7 @@ void check_device_busy_timeout()
<< dev.busytimecount << "s)" << std::endl; << dev.busytimecount << "s)" << std::endl;
//发送超时响应 //发送超时响应
send_reply_to_cloud(static_cast<int>(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype)); send_reply_to_cloud(static_cast<int>(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype),dev.guid,dev.mac);
// 超时清空状态 // 超时清空状态
dev.guid.clear(); // 清空进行中的 guid dev.guid.clear(); // 清空进行中的 guid
@@ -3450,7 +3478,7 @@ void check_device_busy_timeout()
<< " 超时(" << dev.busytimecount << "s)" << std::endl; << " 超时(" << dev.busytimecount << "s)" << std::endl;
//发送超时响应 //发送超时响应
send_reply_to_cloud(static_cast<int>(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype)); send_reply_to_cloud(static_cast<int>(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype),dev.guid,dev.mac);
// 超时清空状态 // 超时清空状态
dev.guid.clear(); dev.guid.clear();
@@ -3862,7 +3890,7 @@ bool send_internal_value_reply(const std::string &dev_id, const std::vector<DZ_k
int nStep = 0; // [新增] 每个 NameFixValue 递增 int nStep = 0; // [新增] 每个 NameFixValue 递增
int kSort = 1; // [新增] 排序号,从 1 开始 int kSort = 1; // [新增] 排序号,从 1 开始
// 保护dz_internal_info_list 是引用成员,确保不会因并发被改动(当前已在 ledgermtx 下) // 保护dz_internal_info_list 是引用成员,确保不会因并发被改动
//for (const auto& nf : dev.dz_internal_info_list) { // [新增] //for (const auto& nf : dev.dz_internal_info_list) { // [新增]
for (size_t idxNF = 0; idxNF < n_use; ++idxNF) { // [修改] 使用 idxNF 控制索引 for (size_t idxNF = 0; idxNF < n_use; ++idxNF) { // [修改] 使用 idxNF 控制索引
const auto& nf = dev.dz_internal_info_list[idxNF]; const auto& nf = dev.dz_internal_info_list[idxNF];
@@ -3982,24 +4010,6 @@ bool send_internal_value_reply(const std::string &dev_id, const std::vector<DZ_k
return true; return true;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////清空运行状态
// 清理指定 terminal_id 的运行时状态
void clear_terminal_runtime_state(const std::string& id) {
std::lock_guard<std::mutex> lock(ledgermtx); // 加锁保证线程安全
for (auto& dev : terminal_devlist) {
if (dev.terminal_id == id) {
dev.guid.clear(); // 清空 guid
dev.busytype = 0; // 业务类型归零
dev.isbusy = 0; // 清空业务标志
dev.busytimecount = 0; // 计时归零
std::cout << "[clear_terminal_runtime_state] Cleared runtime state for terminal_id="
<< id << std::endl;
break; // 找到后跳出
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////处理补招逻辑 //////////////////////////////////////////////////////////////////////////////////////////////////////////////处理补招逻辑
//发送补招响应给web //发送补招响应给web
void send_reply_to_kafka_recall(const std::string& guid, const std::string& step,int code, const std::string& result,const std::string& terminalId,const std::string& lineIndex,const std::string& recallStartDate,const std::string& recallEndDate){ void send_reply_to_kafka_recall(const std::string& guid, const std::string& step,int code, const std::string& result,const std::string& terminalId,const std::string& lineIndex,const std::string& recallStartDate,const std::string& recallEndDate){
@@ -4734,11 +4744,11 @@ void on_device_response_minimal(int response_code,
if (filemenu_cache_take(id, names)) { if (filemenu_cache_take(id, names)) {
//发送目录 //发送目录
send_file_list(id,names); send_file_list(dev,names);
} else { } else {
// 失败响应web并复位为空闲 // 失败响应web并复位为空闲
send_reply_to_cloud(static_cast<int>(ResponseCode::BAD_REQUEST), id, static_cast<int>(DeviceState::READING_FILEMENU)); send_reply_to_cloud(static_cast<int>(ResponseCode::BAD_REQUEST), id, static_cast<int>(DeviceState::READING_FILEMENU),dev->guid,dev->mac);
std::cout << "[RESP][FILEMENU->FILEMENU][WARN] dev=" << id std::cout << "[RESP][FILEMENU->FILEMENU][WARN] dev=" << id
<< " names missing in cache" << std::endl; << " names missing in cache" << std::endl;
} }
@@ -4751,7 +4761,7 @@ void on_device_response_minimal(int response_code,
std::cout << "[RESP][FILEMENU->FILEMENU][OK] dev=" << id << std::endl; std::cout << "[RESP][FILEMENU->FILEMENU][OK] dev=" << id << std::endl;
} else { } else {
// 失败响应web并复位为空闲 // 失败响应web并复位为空闲
send_reply_to_cloud(response_code, id, static_cast<int>(DeviceState::READING_FILEMENU)); send_reply_to_cloud(response_code, id, static_cast<int>(DeviceState::READING_FILEMENU),dev->guid,dev->mac);
dev->guid.clear(); dev->guid.clear();
dev->isbusy = 0; dev->isbusy = 0;
@@ -4842,7 +4852,7 @@ void on_device_response_minimal(int response_code,
// ====== 分支 A当前业务就是“读取文件数据” ====== // ====== 分支 A当前业务就是“读取文件数据” ======
if (ok) { if (ok) {
// 成功:复位 // 成功:复位
send_reply_to_cloud(static_cast<int>(ResponseCode::OK), id, static_cast<int>(DeviceState::READING_FILEDATA)); send_reply_to_cloud(static_cast<int>(ResponseCode::OK), id, static_cast<int>(DeviceState::READING_FILEDATA),dev->guid,dev->mac);
dev->guid.clear(); dev->guid.clear();
dev->isbusy = 0; dev->isbusy = 0;
@@ -4851,7 +4861,7 @@ void on_device_response_minimal(int response_code,
std::cout << "[RESP][FILEDATA->FILEDATA][OK] dev=" << id << std::endl; std::cout << "[RESP][FILEDATA->FILEDATA][OK] dev=" << id << std::endl;
} else { } else {
// 失败响应web并复位 // 失败响应web并复位
send_reply_to_cloud(response_code, id, static_cast<int>(DeviceState::READING_FILEDATA)); send_reply_to_cloud(response_code, id, static_cast<int>(DeviceState::READING_FILEDATA),dev->guid,dev->mac);
dev->guid.clear(); dev->guid.clear();
dev->isbusy = 0; dev->isbusy = 0;
@@ -4926,15 +4936,26 @@ void on_device_response_minimal(int response_code,
// ================= 其它状态统一处理 ================= // ================= 其它状态统一处理 =================
default: { default: {
std::lock_guard<std::mutex> lk(ledgermtx);
terminal_dev* dev = nullptr;
for (auto& d : terminal_devlist) {
if (d.terminal_id == id) { dev = &d; break; }
}
if (dev) {
//直接根据输入响应mq //直接根据输入响应mq
send_reply_to_cloud(response_code, id, device_state_int); send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac);
//其他的错误和成功都会结束业务 //其他的错误和成功都会结束业务
clear_terminal_runtime_state(id); dev->guid.clear(); // 清空 guid
dev->busytype = 0; // 业务类型归零
dev->isbusy = 0; // 清空业务标志
dev->busytimecount = 0; // 计时归零
std::cout << "[clear_terminal_runtime_state] Cleared runtime state for terminal_id="
<< id << std::endl;
}
break; break;
} }
} } // end switch
} }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////记录暂态事件到本地 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////记录暂态事件到本地

View File

@@ -181,14 +181,14 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) {
std::cout << "File URL: " << url << std::endl; std::cout << "File URL: " << url << std::endl;
// 找到最后一个 '.' // 找到最后一个 '.'
size_t pos = fileName.find_last_of('.'); size_t pos = name.find_last_of('.');
std::string nameWithoutExt; std::string nameWithoutExt;
if (pos != std::string::npos) { if (pos != std::string::npos) {
// 截取去掉后缀的部分 // 截取去掉后缀的部分
nameWithoutExt = fileName.substr(0, pos); nameWithoutExt = name.substr(0, pos);
} else { } else {
// 如果没有后缀,直接使用原文件名 // 如果没有后缀,直接使用原文件名
nameWithoutExt = fileName; nameWithoutExt = name;
} }
// 拷贝到 wavepath // 拷贝到 wavepath
@@ -1341,7 +1341,7 @@ bool get_monitor_id_by_dev_and_seq(const std::string& terminal_id,
unsigned short logical_seq, unsigned short logical_seq,
std::string& out_monitor_id) std::string& out_monitor_id)
{ {
std::lock_guard<std::mutex> lk(ledgermtx); // 若你的工程里有全局 ledgermtx/terminal_devlist std::lock_guard<std::mutex> lk(ledgermtx);
for (const auto& dev : terminal_devlist) { for (const auto& dev : terminal_devlist) {
if (dev.terminal_id != terminal_id) continue; if (dev.terminal_id != terminal_id) continue;

View File

@@ -611,11 +611,10 @@ bool assign_qvvr_file_list(const std::string& id, ushort nCpuNo, const std::vect
bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id); bool update_qvvr_file_download(const std::string& filename_with_mac, const std::string& terminal_id);
//上送文件列表接口 //上送文件列表接口
bool send_file_list(const std::string &dev_id, const std::vector<tag_dir_info> &FileList); bool send_file_list(terminal_dev* dev, const std::vector<tag_dir_info> &FileList);
//提取mac //提取mac
std::string normalize_mac(const std::string& mac); std::string normalize_mac(const std::string& mac);
std::string get_mac_by_devid(const std::string &devid);
//暂态文件超时检测 //暂态文件超时检测
void check_and_backup_qvvr_files(); void check_and_backup_qvvr_files();
@@ -624,10 +623,7 @@ void check_and_backup_qvvr_files();
void check_device_busy_timeout(); void check_device_busy_timeout();
//业务上报 //业务上报
void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type); void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, const std::string& guid, const std::string& mac);
//查guid
std::string find_guid_index_from_dev_id(const std::string& dev_id);
//内部定值响应 //内部定值响应
bool send_internal_value_reply(const std::string &dev_id, const std::vector<DZ_kzz_bit> &control_words); bool send_internal_value_reply(const std::string &dev_id, const std::vector<DZ_kzz_bit> &control_words);
@@ -650,8 +646,6 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const
//状态翻转 //状态翻转
void connect_status_update(const std::string& id, int status); void connect_status_update(const std::string& id, int status);
//业务停止
void clear_terminal_runtime_state(const std::string& id);
//业务响应 //业务响应
void on_device_response_minimal(int response_code, void on_device_response_minimal(int response_code,

View File

@@ -341,40 +341,6 @@ void my_rocketmq_send(queue_data_t& data,rocketmq::RocketMQProducer* producer)
rocketmq_producer_send(producer,senddata,topic,tag,key); rocketmq_producer_send(producer,senddata,topic,tag,key);
} }
/////////////////////////////////////////////////////////////////////////////////////////////////查找台账下标
// 根据终端 ID 查找 terminal_devlist 中的索引,找不到返回 -1
int find_dev_index_from_dev_id(const std::string& dev_id) {
std::lock_guard<std::mutex> lock(ledgermtx);
for (size_t i = 0; i < terminal_devlist.size(); ++i) {
if (terminal_devlist[i].terminal_id == dev_id) {
return static_cast<int>(i);
}
}
return -1; // 未找到
}
int find_mp_index_from_mp_id(const std::string& mp_id) {
std::lock_guard<std::mutex> lock(ledgermtx);
for (const auto& dev : terminal_devlist) {
for (size_t j = 0; j < dev.line.size(); ++j) {
if (dev.line[j].monitor_id == mp_id) {
return static_cast<int>(j); // 返回 line[] 的下标
}
}
}
return -1; // 未找到
}
std::string find_guid_index_from_dev_id(const std::string& dev_id) {
std::lock_guard<std::mutex> lock(ledgermtx);
for (size_t i = 0; i < terminal_devlist.size(); ++i) {
if (terminal_devlist[i].terminal_id == dev_id) {
return terminal_devlist[i].guid;
}
}
return ""; // 未找到
}
/////////////////////////////////////////////////////////////////////////////////////////////////回调函数的json处理 /////////////////////////////////////////////////////////////////////////////////////////////////回调函数的json处理
bool parseJsonMessageRT(const std::string& body,std::string& devSeries,ushort& line,bool& realData,bool& soeData,int& limit){ bool parseJsonMessageRT(const std::string& body,std::string& devSeries,ushort& line,bool& realData,bool& soeData,int& limit){
@@ -1489,7 +1455,7 @@ void rocketmq_test_rt(Front* front)//用来测试实时数据
queue_data_t data; queue_data_t data;
data.monitor_no = 123; data.monitor_no = 123;
data.strTopic = std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_RT; data.strTopic = G_MQCONSUMER_TOPIC_RT;
std::ifstream file("rt.txt"); // 文件中存储长字符串 std::ifstream file("rt.txt"); // 文件中存储长字符串
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容 buffer << file.rdbuf(); // 读取整个文件内容
@@ -1513,7 +1479,7 @@ void rocketmq_test_ud(Front* front)//用来测试台账更新
queue_data_t data; queue_data_t data;
data.monitor_no = 123; data.monitor_no = 123;
data.strTopic = std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_UD; data.strTopic = G_MQCONSUMER_TOPIC_UD;
std::ifstream file("ud.txt"); // 文件中存储长字符串 std::ifstream file("ud.txt"); // 文件中存储长字符串
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容 buffer << file.rdbuf(); // 读取整个文件内容
@@ -1537,7 +1503,7 @@ void rocketmq_test_set(Front* front)//用来测试进程控制脚本
queue_data_t data; queue_data_t data;
data.monitor_no = 123; data.monitor_no = 123;
data.strTopic = std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_SET; data.strTopic = G_MQCONSUMER_TOPIC_SET;
std::ifstream file("set.txt"); // 文件中存储长字符串 std::ifstream file("set.txt"); // 文件中存储长字符串
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容 buffer << file.rdbuf(); // 读取整个文件内容
@@ -1561,7 +1527,7 @@ void rocketmq_test_rc(Front* front)//用来测试补招
queue_data_t data; queue_data_t data;
data.monitor_no = 123; data.monitor_no = 123;
data.strTopic = std::string(FRONT_INST) + "_" + G_MQCONSUMER_TOPIC_RC; data.strTopic = G_MQCONSUMER_TOPIC_RC;
std::ifstream file("rc.txt"); // 文件中存储长字符串 std::ifstream file("rc.txt"); // 文件中存储长字符串
std::stringstream buffer; std::stringstream buffer;
buffer << file.rdbuf(); // 读取整个文件内容 buffer << file.rdbuf(); // 读取整个文件内容
@@ -1871,9 +1837,9 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
} }
//心跳和其他响应 //心跳和其他响应
void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type) { void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, const std::string& guid, const std::string& mac) {
try { try {
std::string guid = find_guid_index_from_dev_id(dev_id); /*std::string guid = find_guid_index_from_dev_id(dev_id);*/
if(guid == "") if(guid == "")
{ {
std::cerr << "dev: " << dev_id << " guid not found" << std::endl; std::cerr << "dev: " << dev_id << " guid not found" << std::endl;
@@ -1887,8 +1853,8 @@ void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type) {
obj["Node"] = g_front_seg_index; obj["Node"] = g_front_seg_index;
// Dev_mac从台账取 addr_str 并规范化 // Dev_mac从台账取 addr_str 并规范化
std::string mac = get_mac_by_devid(dev_id); //std::string mac = get_mac_by_devid(dev_id);
obj["Dev_mac"] = mac; obj["Dev_mac"] = normalize_mac(mac);
// ---- 构造 Detail ---- // ---- 构造 Detail ----
nlohmann::json detail; nlohmann::json detail;

View File

@@ -2,18 +2,21 @@
BrokerList= BrokerList=
RTDataTopic=Real_Time_Data_Topic RTDataTopic=Real_Time_Data_Topic
HisTopic=LN_Topic HisTopic=njcnAppAutoDataTopic
PSTTopic=LN_Topic PSTTopic=njcnAppAutoDataTopic
PLTTopic=LN_Topic PLTTopic=njcnAppAutoDataTopic
AlmTopic=AlmTopic AlmTopic=AlmTopic
SngTopic=SngTopic SngTopic=SngTopic
QUEUE_TAG=Test_Tag QUEUE_TAG=stat
QUEUE_KEY=Test_Keys QUEUE_KEY=stat
RT_TAG=rt
RT_KEY=rt
[Flag] [Flag]
FrontInst=22de160455a30cc2154890e5502d6433 FrontInst=914b94563ca7f272c90ee8580ed6adc6
FrontIP=192.168.1.67 FrontIP=192.168.1.138
[Ledger] [Ledger]
TerminalStatus="[0]" TerminalStatus="[0]"
@@ -22,35 +25,34 @@ IcdFlag=0
IedCount=300 IedCount=300
[Http] [Http]
WebDevice=http://192.168.1.67:10202/nodeDevice/nodeDeviceList WebDevice=http://192.168.1.103:10220/icd/getLedgerInfo
WebIcd=http://192.168.1.67:10202/icd/icdPathList WebEvent=http://192.168.1.103:10222/event/addCldEvent
WebEvent=http://192.168.1.67:10203/event/addEventDetail WebFileupload=http://192.168.1.103:10207/file/upload
WebFileupload=http://192.168.1.67:10207/file/upload WebFiledownload=
WebFiledownload=http://192.168.1.67:10207/file/download
[RocketMq] [RocketMq]
producer=Group_producer producer=Group_producer
Ipport=192.168.1.24:9876 Ipport=192.168.1.103:9876
AccessKey=rmquser AccessKey=rmqroot
SecretKey=001njcnmq SecretKey=001@#njcnmq
Topic_Test=LN_Topic Topic_Test=lnk_Topic
Tag_Test=Test_Tag Tag_Test=Test_Tag
Key_Test=Test_Keys Key_Test=Test_Keys
Testflag=1 Testflag=1
Testnum=400 Testnum=0
Testtype=1 Testtype=0
TestPort=11000 TestPort=11000
TestList=8ad28e2e36dfbd19906f9e2a4894b375 TestList=
consumer=Group_consumer consumer=Group_consumer
ConsumerIpport=192.168.1.24:9876 ConsumerIpport=192.168.1.103:9876
ConsumerTopicRT=ask_real_data_topic ConsumerTopicRT=ask_real_data_topic
ConsumerTagRT=Test_Tag ConsumerTagRT=Test_Tag
ConsumerKeyRT=Test_Keys ConsumerKeyRT=Test_Keys
ConsumerAccessKey=rmquser ConsumerAccessKey=rmqroot
ConsumerSecretKey=001njcnmq ConsumerSecretKey=001@#njcnmq
ConsumerChannel= ConsumerChannel=
ConsumerTopicUD=control_Topic ConsumerTopicUD=control_Topic
ConsumerTagUD=Test_Tag ConsumerTagUD=Test_Tag