修改了装置重连相关代码,调整了状态翻转通知方法。增加了30分钟定时对时功能。
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
// 配置参数
|
||||
constexpr int BASE_RECONNECT_DELAY = 20000; // 基础重连延迟(ms)
|
||||
@@ -312,6 +314,48 @@ void ClientContext::clear_float_cache() {
|
||||
std::lock_guard<std::mutex> lock(float_cache_mutex_);
|
||||
point_float_cache_.clear();
|
||||
}
|
||||
// 版本比较函数的辅助函数:分割字符串并转换为整数向量
|
||||
std::vector<int> splitVersionString(const std::string& versionStr) {
|
||||
std::vector<int> segments;
|
||||
std::stringstream ss(versionStr);
|
||||
std::string segment;
|
||||
|
||||
while (std::getline(ss, segment, '.')) {
|
||||
segments.push_back(std::stoi(segment));
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
// 版本比较函数
|
||||
bool isVersionGreaterOrEqual(const std::string& version1, const std::string& version2) {
|
||||
// 去除开头的'V'(如果存在)
|
||||
std::string v1 = version1;
|
||||
if (!v1.empty() && v1[0] == 'V') {
|
||||
v1.erase(0, 1);
|
||||
}
|
||||
|
||||
std::string v2 = version2;
|
||||
if (!v2.empty() && v2[0] == 'V') {
|
||||
v2.erase(0, 1);
|
||||
}
|
||||
|
||||
// 分割版本号
|
||||
std::vector<int> seg1 = splitVersionString(v1);
|
||||
std::vector<int> seg2 = splitVersionString(v2);
|
||||
|
||||
// 逐段比较版本号
|
||||
size_t maxSize = std::max(seg1.size(), seg2.size());
|
||||
for (size_t i = 0; i < maxSize; ++i) {
|
||||
int num1 = (i < seg1.size()) ? seg1[i] : 0;
|
||||
int num2 = (i < seg2.size()) ? seg2[i] : 0;
|
||||
|
||||
if (num1 != num2) {
|
||||
return num1 > num2;
|
||||
}
|
||||
}
|
||||
|
||||
return true; // 所有段都相等
|
||||
}
|
||||
|
||||
/* 缓冲区分配回调 */
|
||||
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||
buf->base = new char[suggested_size];
|
||||
@@ -365,6 +409,14 @@ void on_timer(uv_timer_t* handle) {
|
||||
// 检查状态超时 30秒状态未更新则重置为空闲状态
|
||||
ctx->check_state_timeout();
|
||||
|
||||
//检查当前装置最新通讯时间是否超过1分钟,如果1分钟内没有收到任何装置通讯消息,则调整为未登录状态,通讯状态设置为离线.
|
||||
uint64_t timecheck = uv_now(ctx->loop);//当前时间戳
|
||||
if (timecheck - ctx->get_cloudmessage_time >= 60000) {
|
||||
ctx->get_cloudmessage_time = timecheck;
|
||||
//不管原状态是什么,这里都设置装置登录状态为未登录
|
||||
ClientManager::instance().set_cloud_status(ctx->device_info.device_id, 0);
|
||||
}
|
||||
|
||||
// 装置登录成功后,只在空闲状态处理后续动作
|
||||
if (ctx->cloudstatus == 1) {
|
||||
uint64_t now = uv_now(ctx->loop);//当前时间戳
|
||||
@@ -396,11 +448,39 @@ void on_timer(uv_timer_t* handle) {
|
||||
auto sendbuff = generate_machinestatus_message();//组装读取装置运行信息报文
|
||||
ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_2, sendbuff);//将该状态以及待发送报文存入队列
|
||||
}
|
||||
//30分钟一次 启动装置对时 仅在台账开启对时且云协议版本大于1.5时开启对时 60000 * 30
|
||||
now = uv_now(ctx->loop);
|
||||
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->right_time >= 60000 * 30 && ctx->device_info.righttime && isVersionGreaterOrEqual(ctx->dev_CloudProtocolVer,"V1.5"))
|
||||
{
|
||||
// 更新对时功能最后运行时间
|
||||
ctx->right_time = now;
|
||||
|
||||
// 获取当前时间
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::time_t time = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm tm_time = *std::localtime(&time);
|
||||
auto sendbuff = generate_righttime_message(tm_time);//组装装置对时报文
|
||||
ctx->add_action(DeviceState::SET_RIGHTTIME, sendbuff);//将该状态以及待发送报文存入队列
|
||||
//auto sendbuff = generate_machinestatus_message();//组装读取装置运行信息报文
|
||||
//ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_2, sendbuff);//将该状态以及待发送报文存入队列
|
||||
}
|
||||
//处理后续工作队列的工作 取出一个并执行
|
||||
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||
ctx->process_next_action();
|
||||
}
|
||||
}
|
||||
else {
|
||||
//装置登录状态异常,预备重发登录报文,检查最新登录报文发送时间,超过限制则重发登录报文
|
||||
uint64_t now = uv_now(ctx->loop);//当前时间戳
|
||||
if (now - ctx->login_cloud_time >= 60000) {
|
||||
//更新最后一次登录报文发送时间
|
||||
ctx->login_cloud_time = now;
|
||||
|
||||
//装置未登录,且60秒内没有发送装置登录报文,预备发送登录报文
|
||||
auto binary_data = generate_frontlogin_message(ctx->device_info.mac);
|
||||
safe_send_binary_data(ctx, binary_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 发送二进制报文函数 */
|
||||
@@ -470,8 +550,8 @@ void on_close(uv_handle_t* handle) {
|
||||
ctx->clear_stat_cache();
|
||||
// 清除浮点数据缓存
|
||||
ctx->clear_float_cache();
|
||||
|
||||
ctx->cloudstatus = 0;
|
||||
// 装置登录状态调整为离线
|
||||
ClientManager::instance().set_cloud_status(ctx->device_info.device_id, 0);
|
||||
{
|
||||
std::lock_guard<std::mutex> state_lock(ctx->state_mutex_);
|
||||
ctx->current_state_ = DeviceState::IDLE; // 直接修改状态
|
||||
@@ -542,6 +622,9 @@ void on_connect(uv_connect_t* req, int status) {
|
||||
ctx->last_state_query_time_ = uv_now(ctx->loop);//初始化统计数据时间戳
|
||||
ctx->real_state_query_time_ = uv_now(ctx->loop);//初始化实时数据时间戳
|
||||
ctx->read_runninginformationMsg = uv_now(ctx->loop);//初始化读取装置运行信息时间戳
|
||||
ctx->right_time = uv_now(ctx->loop);//初始化对时时间戳
|
||||
ctx->get_cloudmessage_time = uv_now(ctx->loop);//初始化最新装置通讯报文时间戳
|
||||
ctx->login_cloud_time = uv_now(ctx->loop);//初始化装置登录报文超时发送时标
|
||||
ctx->real_state_count = 0;//实时数据收发计数
|
||||
//客户端连接完毕后,发送装置登陆消息
|
||||
std::cout << "connected: " << ctx->device_info.mac << " send login msg!" << std::endl;
|
||||
@@ -727,6 +810,17 @@ bool ClientManager::set_cloud_status(const std::string& identifier, int status)
|
||||
if (ctx->device_info.device_id == identifier ||
|
||||
ctx->device_info.mac == identifier) {
|
||||
|
||||
if (ctx->cloudstatus == 0 && status == 1) {
|
||||
//设备从离线转换至在线,通知前台状态发生翻转
|
||||
std::cout << "[Device " << identifier
|
||||
<< "] ****Cloud status: " << ctx->cloudstatus << " updated to: " << status << std::endl;
|
||||
}
|
||||
else if (ctx->cloudstatus == 1 && status == 0) {
|
||||
//设备从在线转换至离线,通知前台状态发生翻转
|
||||
std::cout << "[Device " << identifier
|
||||
<< "] ****Cloud status: " << ctx->cloudstatus << " updated to: " << status << std::endl;
|
||||
}
|
||||
|
||||
// 修改云前置登录状态
|
||||
ctx->cloudstatus = status;
|
||||
std::cout << "[Device " << identifier
|
||||
@@ -739,6 +833,48 @@ bool ClientManager::set_cloud_status(const std::string& identifier, int status)
|
||||
return false;
|
||||
}
|
||||
|
||||
//刷新客户端装置最新接收通讯报文时间
|
||||
bool ClientManager::set_cloudmessage_time(const std::string& identifier) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
for (auto& pair : clients_) {
|
||||
auto& ctx = pair.second;
|
||||
// 匹配装置ID或MAC地址
|
||||
if (ctx->device_info.device_id == identifier ||
|
||||
ctx->device_info.mac == identifier) {
|
||||
|
||||
// 修改云前置登录状态
|
||||
ctx->get_cloudmessage_time = uv_now(ctx->loop);//刷新最新装置通讯报文时间戳
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "[set_cloud_status] Device not found: " << identifier << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//修改客户端读取到的配置信息:云协议版本
|
||||
bool ClientManager::set_versioninformation(const std::string& identifier, string cloud_version) {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
for (auto& pair : clients_) {
|
||||
auto& ctx = pair.second;
|
||||
// 匹配装置ID或MAC地址
|
||||
if (ctx->device_info.device_id == identifier ||
|
||||
ctx->device_info.mac == identifier) {
|
||||
|
||||
// 修改云前置登录状态
|
||||
ctx->dev_CloudProtocolVer = cloud_version;
|
||||
std::cout << "[Device " << identifier
|
||||
<< "] Cloud version updated to: " << cloud_version << std::endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "[set_cloud_status] Device not found: " << identifier << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientManager::add_action_to_device(const std::string& identifier,
|
||||
DeviceState state,
|
||||
const std::vector<unsigned char>& packet) {
|
||||
|
||||
Reference in New Issue
Block a user