#include "ToWeb.h" namespace ai_matrix { const int TIME_DIFF = 28800; // 8 hour ToWeb *ToWeb::ins = nullptr; ToWeb::GarbageCollector ToWeb::gc; std::mutex ToWeb::mx; ToWeb *ToWeb::getins() { //双层锁,确保线程安全 if (ins == nullptr) { std::lock_guard guard(mx); //防止异常发生不能解锁 if (ins == nullptr) { ins = new ToWeb(); } } return ins; } void ToWeb::setConfig(const HttpServerConfig &httpConfig) { this->httpConfig_ = httpConfig; } bool ToWeb::getToken() { try { httplib::Client cli(this->httpConfig_.strIp, this->httpConfig_.iPort); cli.set_connection_timeout(0, 300 * 1000); cli.set_read_timeout(0,300*1000); httplib::Headers header; httplib::Params params; header.emplace("Authorization", "Basic Y2xpZW50X2VudGVycHJpc2U6Y2xpZW50X2VudGVycHJpc2Vfc2VjcmV0"); params.emplace("username", this->httpConfig_.strUserName); params.emplace("password", this->httpConfig_.strPassword); params.emplace("tenantId", "000000"); params.emplace("grant_type", "password"); auto res = cli.Post(this->httpConfig_.strTokenUrl, header, params); if (res) { if (res->status == 200) { Json::CharReaderBuilder readerBuilder; std::istringstream iss(res->body); Json::Value root; std::string errs; bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); if (parsingSuccessful) { if (!root.get("token_type", "").asString().empty()) { this->webToken = root["token_type"].asString(); this->webToken.append(" "); this->webToken.append(root["access_token"].asString()); LogInfo << "已获取到web token"; return true; } else { LogError << "获取web token失败,原因:" << res->body; } } else { LogError << "获取web token返回数据解析异常,返回数据非json。详细:" << res->body; } } } else { auto err = res.error(); // if (err == httplib::Error::Connection) { // std::cout << " (连接出错)" << std::endl; // } LogError << "获取web token失败!请检查网络或请求地址。详细:" << to_string(err); } } catch (std::exception &e) { LogError << "获取授权失败,原因:"; LogError << e.what(); } return false; } bool ToWeb::upWeb(const Json::Value &jvRequest, int retransmission) { try { Json::StreamWriterBuilder writer; std::string str = Json::writeString(writer, jvRequest); LogInfo << "第" << jvRequest["carriageOrder"].asInt() << "节,发送web: " << str; httplib::Client cli(this->httpConfig_.strIp, this->httpConfig_.iPort); cli.set_connection_timeout(0, 300 * 1000); cli.set_read_timeout(3,0); httplib::Headers header; httplib::Params params; header.emplace("blade-auth", this->webToken); //header.emplace("Content-Type", "application/json"); auto res = cli.Post(this->httpConfig_.strUpResultUrl, header, str, "application/json"); if (res) { if (res->status == 200) { LogInfo << "第" << jvRequest["carriageOrder"].asInt() << "节,web返回: " << res->body; Json::CharReaderBuilder readerBuilder; std::istringstream iss(res->body); Json::Value root; std::string errs; bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); if (parsingSuccessful) { if (root["success"].asBool()) { return true; } else { if (root["msg"].asString() == "请求未授权") { LogWarn << "第" << jvRequest["carriageOrder"].asInt() << "节,因请求未授权,而上传识别结果失败!重新请求token。"; if (!this->getToken()) return false; return this->upWeb(jvRequest, retransmission); } LogError << "第" << jvRequest["carriageOrder"].asInt() << "节,识别结果上传失败,原因:" << root["msg"].asString(); } } else { LogError << "第" << jvRequest["carriageOrder"].asInt() << "节,识别结果上传失败,返回数据解析异常,返回数据非json:" + res->body; } } else { LogError << "第" << jvRequest["carriageOrder"].asInt() << "节,识别结果上传失败,原因:" << res->status << " - " << res->body; if (res->status == 401) { LogWarn << "因请求未授权,而上传识别结果失败!重新请求token。"; this->getToken(); return this->upWeb(jvRequest, retransmission); } } } else { LogError << "第" << jvRequest["carriageOrder"].asInt() << "节,上传数据失败(超时),请检查网络,或者上传地址!计划重新上传次数:" << retransmission; if (retransmission > 0) return this->upWeb(jvRequest, --retransmission); } } catch (std::exception &e) { LogError << "第" << jvRequest["carriageOrder"].asInt() << "节,上传识别结果失败,原因:"; LogError << e.what(); } return false; } bool ToWeb::upDeviceStatus(const Json::Value &jvRequest, int retransmission) { try { Json::StreamWriterBuilder writer; std::string str = Json::writeString(writer, jvRequest); LogInfo << "设备状态报警,发送web: " << str; httplib::Client cli(this->httpConfig_.strIp, this->httpConfig_.iPort); cli.set_connection_timeout(0, 300 * 1000); cli.set_read_timeout(3,0); httplib::Headers header; httplib::Params params; header.emplace("blade-auth", this->webToken); //header.emplace("Content-Type", "application/json"); auto res = cli.Post(this->httpConfig_.strUpDeviceStatusUrl, header, str, "application/json"); if (res) { if (res->status == 200) { LogInfo << "设备状态报警,web返回: " << res->body; Json::CharReaderBuilder readerBuilder; std::istringstream iss(res->body); Json::Value root; std::string errs; bool parsingSuccessful = Json::parseFromStream(readerBuilder, iss, &root, &errs); if (parsingSuccessful) { if (root["success"].asBool()) { return true; } else { if (root["msg"].asString() == "请求未授权") { LogWarn << "设备状态报警,因请求未授权,而上传识别状态失败!重新请求token。"; if (!this->getToken()) return false; return this->upDeviceStatus(jvRequest, retransmission); } LogError << "设备状态报警,识别状态上传失败,原因:" << root["msg"].asString(); } } else { LogError << "设备状态报警,识别状态上传失败,返回数据解析异常,返回数据非json:" + res->body; } } else { LogError << "设备状态报警,识别状态上传失败,原因:" << res->status << " - " << res->body; if (res->status == 401) { LogWarn << "因请求未授权,而上传识别状态失败!重新请求token。"; this->getToken(); return this->upDeviceStatus(jvRequest, retransmission); } } } else { LogError << "设备状态报警,上传数据失败(超时),请检查网络,或者上传地址!计划重新上传次数:" << retransmission; if (retransmission > 0) return this->upDeviceStatus(jvRequest, --retransmission); } } catch (std::exception &e) { LogError << "设备状态报警,上传识别状态失败,原因:"; LogError << e.what(); } return false; } }