From ccd7a3bb59867e524c159e2860b2623e2da0adcf Mon Sep 17 00:00:00 2001 From: zw <3466561528@qq.com> Date: Tue, 24 Jun 2025 18:40:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E8=A3=85=E7=BD=AE?= =?UTF-8?q?=E9=80=9A=E8=AE=AF=E7=AE=A1=E7=90=86=EF=BC=8C=E7=8E=B0=E5=9C=A8?= =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=9C=A8=E5=A4=96=E9=83=A8=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E7=9A=84=E6=B7=BB=E5=8A=A0=E5=92=8C=E5=88=A0=E9=99=A4=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E8=AE=BE=E5=A4=87=E4=BA=86,=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=AE=BE=E5=A4=87=E7=9A=84=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=8F=91=E9=80=81=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LFtid1056/client2.cpp | 127 ++++++++++++++++++++++++++++++-------- LFtid1056/client2.h | 42 +++++++++++-- LFtid1056/main_thread.cpp | 18 +++++- 3 files changed, 154 insertions(+), 33 deletions(-) diff --git a/LFtid1056/client2.cpp b/LFtid1056/client2.cpp index 1729d9b..1a91f5e 100644 --- a/LFtid1056/client2.cpp +++ b/LFtid1056/client2.cpp @@ -7,15 +7,16 @@ #include #include #include +#include +#include // 配置参数 constexpr int BASE_RECONNECT_DELAY = 5000; // 基础重连延迟(ms) constexpr int MAX_RECONNECT_DELAY = 60000; // 最大重连延迟(ms) -constexpr const char* SERVER_IP = "101.132.39.45"; // 目标服务器IP -constexpr int SERVER_PORT = 1056; // 目标服务器端口 +constexpr const char* SERVER_IP = "172.25.144.1"; // 目标服务器IP"101.132.39.45" +constexpr int SERVER_PORT = 61000; // 目标服务器端口1056 static uv_loop_t* global_loop = nullptr; -static std::vector> client_contexts; static uv_timer_t monitor_timer; extern SafeMessageQueue message_queue; @@ -107,15 +108,16 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { // 复制测点信息 msg.points = ctx->device_info.points; - msg.data = new char[nread]; + msg.data = static_cast(malloc(nread)); msg.length = nread; memcpy(msg.data, buf->base, nread); if (!message_queue.push(msg)) { std::cerr << "[Device " << ctx->device_info.device_id << "] Message queue full, dropping message" << std::endl; - delete[] msg.data; + free(msg.data); } + std::cout << "on_read: " << ctx->device_info.mac << " get!" << std::endl; } delete[] buf->base; @@ -129,7 +131,7 @@ void on_write(uv_write_t* req, int status) { std::cerr << "[Device " << ctx->device_info.device_id << "] SEND ERROR: " << uv_strerror(status) << std::endl; } - + std::cout << "on_write: " << ctx->device_info.mac << " down!" << std::endl; delete[] static_cast(req->data); // 释放发送数据缓冲区 delete req; // 释放写入请求 } @@ -141,13 +143,15 @@ void on_timer(uv_timer_t* handle) { if (ctx->state != ConnectionState::CONNECTED) { return; } - + std::cout << "on_timer: " << ctx->device_info.mac << " send!"<< std::endl; // 使用装置自己的MAC地址生成登录报文 auto binary_data = generate_frontlogin_message(ctx->device_info.mac); // 调用发送函数 send_binary_data(ctx, binary_data.data(), binary_data.size()); + //ClientManager::instance().send_to_device(ctx->device_info.mac, binary_data.data(), binary_data.size()); + // 根据装置状态发送其他数据 if (ctx->device_info.status == 1) { // 在线状态 // 可以发送装置配置信息或测点数据 @@ -253,25 +257,18 @@ void on_connect(uv_connect_t* req, int status) { /* 初始化所有客户端连接 */ void init_clients(uv_loop_t* loop, const std::vector& devices) { - client_contexts.clear(); - for (size_t i = 0; i < devices.size(); i++) { - // 修改为C++11兼容的unique_ptr创建方式 - client_contexts.push_back( - std::unique_ptr( - new ClientContext(loop, devices[i], i) - ) - ); - try_reconnect(&client_contexts.back()->reconnect_timer); + auto& manager = ClientManager::instance(); + manager.set_loop(loop); // 使用公共方法设置事件循环 + + for (const auto& device : devices) { + manager.add_device(device); } } /* 停止所有客户端 */ void stop_all_clients() { - for (auto& ctx : client_contexts) { - ctx->shutdown = true; - ctx->close_handles(); - } - client_contexts.clear(); + auto& manager = ClientManager::instance(); + manager.stop_all(); } /* 连接监控回调 */ @@ -279,12 +276,12 @@ void monitor_connections(uv_timer_t* handle) { static int recovery_counter = 0; if (++recovery_counter >= 5) { int active_count = 0; - for (const auto& ctx : client_contexts) { - if (ctx->state == ConnectionState::CONNECTED) { - active_count++; - } - } - std::cout << "Active connections: " << active_count << "/" << client_contexts.size() << std::endl; + auto& manager = ClientManager::instance(); + size_t total_clients = manager.client_count(); + + // 实际应用中,这里需要实现获取活动连接数的方法 + // 简化处理,只显示总连接数 + std::cout << "Total connections: " << total_clients << std::endl; recovery_counter = 0; } } @@ -327,4 +324,80 @@ void start_client_connect(const std::vector& devices) { // 清理所有客户端 stop_all_clients(); global_loop = nullptr; +} + +// ClientManager 成员函数实现 +void ClientManager::add_device(const DeviceInfo& device) { + std::lock_guard lock(mutex_); + + if (!loop_) { + std::cerr << "[Device " << device.device_id << "] Cannot add: event loop not set\n"; + return; + } + + // 检查是否已存在相同ID的装置 + if (clients_.find(device.device_id) != clients_.end()) { + std::cerr << "[Device " << device.device_id << "] Already exists, skip adding\n"; + return; + } + + // 创建新的客户端上下文 + int index = clients_.size(); + auto ctx = std::unique_ptr(new ClientContext(loop_, device, index)); + + // 添加到管理映射 + clients_[device.device_id] = std::move(ctx); + + // 启动连接 + try_reconnect(&clients_[device.device_id]->reconnect_timer); + std::cout << "[Device " << device.device_id << "] Added successfully\n"; +} + +void ClientManager::remove_device(const std::string& device_id) { + std::lock_guard lock(mutex_); + + auto it = clients_.find(device_id); + if (it == clients_.end()) { + std::cerr << "[Device " << device_id << "] Not found, cannot remove\n"; + return; + } + + // 关闭连接并移除 + it->second->shutdown = true; + it->second->close_handles(); + clients_.erase(it); + std::cout << "[Device " << device_id << "] Removed successfully\n"; +} + +bool ClientManager::send_to_device(const std::string& identifier, + const unsigned char* data, + size_t size) { + std::lock_guard lock(mutex_); + + for (auto& pair : clients_) { + auto& ctx = pair.second; + // 匹配装置ID或MAC地址 + if (ctx->device_info.device_id == identifier || + ctx->device_info.mac == identifier) { + + if (ctx->state == ConnectionState::CONNECTED) { + send_binary_data(ctx.get(), data, size); + return true; + } + std::cerr << "[Device " << identifier << "] Not connected\n"; + return false; + } + } + + std::cerr << "[Device " << identifier << "] Not found\n"; + return false; +} + +void ClientManager::stop_all() { + std::lock_guard lock(mutex_); + for (auto& pair : clients_) { + pair.second->shutdown = true; + pair.second->close_handles(); + } + clients_.clear(); } \ No newline at end of file diff --git a/LFtid1056/client2.h b/LFtid1056/client2.h index 8b7449b..9cc37d9 100644 --- a/LFtid1056/client2.h +++ b/LFtid1056/client2.h @@ -2,6 +2,8 @@ #include #include #include +#include +#include // Ϣṹ struct PointInfo { @@ -54,10 +56,42 @@ private: int index_; }; +class ClientManager { +public: + static ClientManager& instance() { + static ClientManager inst; + return inst; + } + + // ¼ѭ + void set_loop(uv_loop_t* loop) { + std::lock_guard lock(mutex_); + loop_ = loop; + } + + void add_device(const DeviceInfo& device); + void remove_device(const std::string& device_id); + bool send_to_device(const std::string& identifier, const unsigned char* data, size_t size); + void stop_all(); + // ȡͻ + size_t client_count() { + std::lock_guard lock(mutex_); + return clients_.size(); + } + +private: + ClientManager() : loop_(nullptr) {} + std::unordered_map> clients_; + std::mutex mutex_; + uv_loop_t* loop_; // ¼ѭָ +}; + // void start_client_connect(const std::vector& devices); void send_binary_data(ClientContext* ctx, const unsigned char* data, size_t data_size); -void on_timer(uv_timer_t* handle);//װöʱص -void try_reconnect(uv_timer_t* timer);//װص -void on_connect(uv_connect_t* req, int status);//װӻص -void on_close(uv_handle_t* handle);//װùرջص \ No newline at end of file +void on_timer(uv_timer_t* handle); +void try_reconnect(uv_timer_t* timer); +void on_connect(uv_connect_t* req, int status); +void on_close(uv_handle_t* handle); +void init_clients(uv_loop_t* loop, const std::vector& devices); +void stop_all_clients(); \ No newline at end of file diff --git a/LFtid1056/main_thread.cpp b/LFtid1056/main_thread.cpp index 3a564bd..df7d7f8 100644 --- a/LFtid1056/main_thread.cpp +++ b/LFtid1056/main_thread.cpp @@ -69,7 +69,7 @@ std::vector generate_test_devices(int count) { dev_id, dev_name, (i % 2 == 0) ? "Model-X" : "Model-Y", // ʹͺ - "00-B7-8D-A8-00-D1", // MACַ + "00-B7-8D-A8-00-D6", // MACַ 1, // ״̬ (1=) points }); @@ -185,6 +185,10 @@ void* message_processor_thread(void* arg) { free(msg.data); } + else { + // Ϊʱߣ100΢ = 0.1룩 + usleep(100); + } } // ֹ߳ @@ -306,10 +310,20 @@ int main() { } // socket״̬ - static int queue_monitor = 0; + static int queue_monitor = 0; + //static int count = 3; if (++queue_monitor >= 10) { // ÿ10뱨һ printf("Message queue size: %zu\n", message_queue.size()); queue_monitor = 0; + + /*std::vector test_devices = generate_test_devices(count); + count++; + for (const auto& device : test_devices) { + ClientManager::instance().add_device(device); + } + for (const auto& device : test_devices) { + ClientManager::instance().remove_device("D001"); + }*/ } }