// // Created by 闫鹏宇 on 2022/7/28. // #ifndef OPCUA_EXPORTER_CLIENT_H #define OPCUA_EXPORTER_CLIENT_H #include #include #include #include #include #include #include #include #include #include #include class client final { public: explicit client(std::string endpoint); ~client(); void stop(); void run(); bool connect(); void disconnect(); std::map readValue(std::vector const &node_ids); void readTest(); UA_Client *getClient(); size_t getAsyncReadRequestHashKey(uint32_t req_id); void updateReadValueCache(size_t hash_key, UA_ReadResponse const &response); protected: std::vector makeReadValueIds(std::vector const &node_ids); UA_ReadRequest &makeReadRequest(size_t hash_key); std::map getCacheValue(size_t hash_key); double getValueAsDouble(UA_DataValue const &ua_value); void cachePreCheckAndInit(size_t hash_key, std::vector const &node_ids); void sendReadRequest(size_t hash_key, bool force_sync = false); std::chrono::system_clock::duration getCacheUpdateDuration(size_t hash_key); std::chrono::system_clock::duration getReadRequestDuration(size_t hash_key); void setValueCache(std::string const &node_id, double value); uint32_t *getAsyncReadRequestId(size_t hash_key); void createSubscription(); protected: enum enum_read_mode { SYNC, ASYNC, MONITOR }; struct st_read_value_request_cache { std::chrono::system_clock::time_point last_read_response_time; std::chrono::system_clock::time_point last_read_request_time; std::vector read_value_ids; UA_ReadRequest read_request; std::vector node_ids; }; private: UA_Client *ua_client{nullptr}; UA_ClientConfig ua_config{}; std::string ua_endpoint; std::shared_mutex ua_mutex; std::mutex ua_read_mutex; std::chrono::system_clock::duration cache_timeout{std::chrono::milliseconds(1000)}; std::chrono::system_clock::duration cache_update_time{std::chrono::milliseconds(400)}; enum_read_mode read_mode{ASYNC}; std::unordered_map ua_read_value_request_cache_; std::map ua_read_value_cache; bool running{true}; std::array, 1024> async_read_request_ids; std::atomic_int64_t current_async_read_request_pos{0}; std::optional create_subscription_response; }; #endif //OPCUA_EXPORTER_CLIENT_H