2025-06-13 11:29:59 +08:00
|
|
|
|
#include <uv.h>
|
2025-06-24 10:33:31 +08:00
|
|
|
|
#include <string>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <memory>
|
2025-06-24 18:40:10 +08:00
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
#include <mutex>
|
2025-06-24 10:33:31 +08:00
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
|
|
|
|
|
struct PointInfo {
|
|
|
|
|
|
std::string point_id; // <20><><EFBFBD><EFBFBD>ID
|
|
|
|
|
|
std::string name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
std::string device_id; // <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>ID
|
|
|
|
|
|
double PT1; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>1
|
|
|
|
|
|
double PT2; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>2
|
|
|
|
|
|
double CT1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
|
|
|
|
|
double CT2; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// װ<><D7B0><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
|
|
|
|
|
struct DeviceInfo {
|
|
|
|
|
|
std::string device_id; // װ<><D7B0>ID
|
|
|
|
|
|
std::string name; // װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
std::string model; // װ<><D7B0><EFBFBD>ͺ<EFBFBD>
|
|
|
|
|
|
std::string mac; // װ<><D7B0>MAC<41><43>ַ
|
|
|
|
|
|
int status; // <20><><EFBFBD><EFBFBD>״̬ (0: <20><><EFBFBD><EFBFBD>, 1: <20><><EFBFBD><EFBFBD>)
|
|
|
|
|
|
std::vector<PointInfo> points; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum class ConnectionState {
|
|
|
|
|
|
DISCONNECTED,
|
|
|
|
|
|
CONNECTING,
|
|
|
|
|
|
CONNECTED
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class ClientContext {
|
|
|
|
|
|
public:
|
|
|
|
|
|
uv_loop_t* loop;
|
|
|
|
|
|
uv_tcp_t client;
|
|
|
|
|
|
uv_timer_t timer;
|
|
|
|
|
|
uv_timer_t reconnect_timer;
|
|
|
|
|
|
ConnectionState state;
|
|
|
|
|
|
int reconnect_attempts;
|
|
|
|
|
|
volatile bool shutdown;
|
|
|
|
|
|
DeviceInfo device_info; // װ<><D7B0><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
|
|
|
|
|
|
|
ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index);
|
|
|
|
|
|
~ClientContext();
|
|
|
|
|
|
|
|
|
|
|
|
void init_tcp();
|
|
|
|
|
|
void start_timer();
|
|
|
|
|
|
void start_reconnect_timer(int delay);
|
|
|
|
|
|
void stop_timers();
|
|
|
|
|
|
void close_handles();
|
2025-06-25 10:54:09 +08:00
|
|
|
|
void append_and_process_data(const char* data, size_t len);
|
|
|
|
|
|
void put_packet_into_queue(const std::vector<unsigned char>& packet);
|
2025-06-24 10:33:31 +08:00
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
int index_;
|
2025-06-25 10:54:09 +08:00
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
std::vector<unsigned char> recv_buffer_; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
std::mutex buffer_mutex_; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
void process_buffer();
|
2025-06-24 10:33:31 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2025-06-24 18:40:10 +08:00
|
|
|
|
class ClientManager {
|
|
|
|
|
|
public:
|
|
|
|
|
|
static ClientManager& instance() {
|
|
|
|
|
|
static ClientManager inst;
|
|
|
|
|
|
return inst;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ѭ<EFBFBD><D1AD>
|
|
|
|
|
|
void set_loop(uv_loop_t* loop) {
|
|
|
|
|
|
std::lock_guard<std::mutex> 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();
|
|
|
|
|
|
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
size_t client_count() {
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
|
|
|
|
return clients_.size();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
ClientManager() : loop_(nullptr) {}
|
|
|
|
|
|
std::unordered_map<std::string, std::unique_ptr<ClientContext>> clients_;
|
|
|
|
|
|
std::mutex mutex_;
|
|
|
|
|
|
uv_loop_t* loop_; // <20>¼<EFBFBD>ѭ<EFBFBD><D1AD>ָ<EFBFBD><D6B8>
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-06-24 10:33:31 +08:00
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
void start_client_connect(const std::vector<DeviceInfo>& devices);
|
|
|
|
|
|
void send_binary_data(ClientContext* ctx, const unsigned char* data, size_t data_size);
|
2025-06-24 18:40:10 +08:00
|
|
|
|
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<DeviceInfo>& devices);
|
|
|
|
|
|
void stop_all_clients();
|