You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.5 KiB

#include "HttpClientSync.h"
#include <QCoreApplication>
#include <QUrlQuery>
#include <QTimer>
#include <QDebug>
HttpClientSync::HttpClientSync(QObject* parent /* = nullptr */)
: QObject(parent)
{
}
HttpClientSync::~HttpClientSync() {
}
std::future<std::pair<bool, QJsonDocument>>
HttpClientSync::get(const QUrl& baseUrl, const QString& token, const QMap<QString, QString>& params, int timeoutMs/* = 5000*/) {
auto promise = std::make_shared<std::promise<std::pair<bool, QJsonDocument>>>();
std::future<std::pair<bool, QJsonDocument>> future = promise->get_future();
// 必须在主线程创建QObject
QMetaObject::invokeMethod(QCoreApplication::instance(), [=]() {
QNetworkAccessManager* manager = new QNetworkAccessManager();
QUrl url(baseUrl);
// 加入参数
QUrlQuery query;
for (auto it = params.constBegin(); it != params.constEnd(); ++it) {
query.addQueryItem(it.key(), it.value());
}
if (!query.isEmpty())
url.setQuery(query);
// 创建请求
QNetworkRequest request(url);
// 设置头
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
if (!token.isEmpty()) {
request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8());
}
QNetworkReply* reply = manager->get(request);
// 超时处理
QTimer* timer = nullptr;
if (timeoutMs > 0) {
timer = new QTimer();
timer->setSingleShot(true);
QObject::connect(timer, &QTimer::timeout, [=]() {
reply->abort();
promise->set_value({ false, QJsonDocument() }); // 超时返回
manager->deleteLater();
timer->deleteLater();
});
timer->start(timeoutMs);
}
QObject::connect(reply, &QNetworkReply::finished, [=]() {
if (nullptr != timer)
timer->stop();
if (reply->error() == QNetworkReply::NoError) {
promise->set_value({ true, QJsonDocument::fromJson(reply->readAll()) });
}
else {
promise->set_value({ false, QJsonDocument() });
}
manager->deleteLater();
if (nullptr != timer)
timer->deleteLater();
});
});
return future;
}
std::future<std::pair<bool, QJsonDocument>>
HttpClientSync::post(const QUrl& url, const QJsonObject& data, const QString& token /* = "" */, int timeoutMs /* = 5000 */) {
auto promise = std::make_shared<std::promise<std::pair<bool, QJsonDocument>>>();
auto future = promise->get_future();
QMetaObject::invokeMethod(QCoreApplication::instance(), [=]() {
QNetworkAccessManager* manager = new QNetworkAccessManager();
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
if (!token.isEmpty()) {
request.setRawHeader("Authorization", "Bearer " + token.toUtf8());
}
// 准备POST数据
QByteArray postData = QJsonDocument(data).toJson();
QNetworkReply* reply = manager->post(request, postData);
QTimer* timer = new QTimer();
timer->setSingleShot(true);
// 超时处理
QObject::connect(timer, &QTimer::timeout, [=]() {
reply->abort();
promise->set_value({ false, QJsonDocument() });
manager->deleteLater();
timer->deleteLater();
});
timer->start(timeoutMs);
// 响应处理
QObject::connect(reply, &QNetworkReply::finished, [=]() {
timer->stop();
bool success = false;
QJsonDocument json;
if (reply->error() == QNetworkReply::NoError) {
QJsonParseError parseError;
json = QJsonDocument::fromJson(reply->readAll(), &parseError);
success = (parseError.error == QJsonParseError::NoError);
}
promise->set_value({ success, json });
manager->deleteLater();
timer->deleteLater();
});
});
return future;
}