Files
hfut-bishe/client/core/net/ModelServerClient.cpp
2026-04-07 20:55:30 +08:00

140 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "net/ModelServerClient.h"
#include <QEventLoop>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTimer>
#include <QUrl>
namespace core {
ModelServerClient::ModelServerClient(QObject* parent)
: QObject(parent)
, m_nam(new QNetworkAccessManager(this)) {
}
void ModelServerClient::setBaseUrl(const QUrl& baseUrl) {
m_baseUrl = baseUrl;
}
QUrl ModelServerClient::baseUrl() const {
return m_baseUrl;
}
QNetworkReply* ModelServerClient::computeDepthPng8Async(const QByteArray& imageBytes, QString* outImmediateError) {
if (outImmediateError) {
outImmediateError->clear();
}
if (!m_baseUrl.isValid() || m_baseUrl.isEmpty()) {
if (outImmediateError) *outImmediateError = QStringLiteral("后端地址无效。");
return nullptr;
}
if (imageBytes.isEmpty()) {
if (outImmediateError) *outImmediateError = QStringLiteral("输入图像为空。");
return nullptr;
}
const QUrl url = m_baseUrl.resolved(QUrl(QStringLiteral("/depth")));
QNetworkRequest req(url);
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
const QByteArray imageB64 = imageBytes.toBase64();
const QJsonObject payload{
{QStringLiteral("image_b64"), QString::fromLatin1(imageB64)},
};
const QByteArray body = QJsonDocument(payload).toJson(QJsonDocument::Compact);
return m_nam->post(req, body);
}
bool ModelServerClient::computeDepthPng8(
const QByteArray& imageBytes,
QByteArray& outPngBytes,
QString& outError,
int timeoutMs
) {
outPngBytes.clear();
outError.clear();
if (!m_baseUrl.isValid() || m_baseUrl.isEmpty()) {
outError = QStringLiteral("后端地址无效。");
return false;
}
if (imageBytes.isEmpty()) {
outError = QStringLiteral("输入图像为空。");
return false;
}
const QUrl url = m_baseUrl.resolved(QUrl(QStringLiteral("/depth")));
QNetworkRequest req(url);
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
const QByteArray imageB64 = imageBytes.toBase64();
const QJsonObject payload{
{QStringLiteral("image_b64"), QString::fromLatin1(imageB64)},
};
const QByteArray body = QJsonDocument(payload).toJson(QJsonDocument::Compact);
QNetworkReply* reply = m_nam->post(req, body);
if (!reply) {
outError = QStringLiteral("创建网络请求失败。");
return false;
}
QEventLoop loop;
QTimer timer;
timer.setSingleShot(true);
const int t = (timeoutMs <= 0) ? 30000 : timeoutMs;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
timer.start(t);
loop.exec();
if (timer.isActive() == false && reply->isFinished() == false) {
reply->abort();
reply->deleteLater();
outError = QStringLiteral("请求超时(%1ms").arg(t);
return false;
}
const int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
const QByteArray raw = reply->readAll();
const auto netErr = reply->error();
const QString netErrStr = reply->errorString();
reply->deleteLater();
if (netErr != QNetworkReply::NoError) {
outError = QStringLiteral("网络错误:%1").arg(netErrStr);
return false;
}
if (httpStatus != 200) {
// FastAPI HTTPException 默认返回 {"detail": "..."}
QString detail;
const QJsonDocument jd = QJsonDocument::fromJson(raw);
if (jd.isObject()) {
const auto obj = jd.object();
detail = obj.value(QStringLiteral("detail")).toString();
}
outError = detail.isEmpty()
? QStringLiteral("后端返回HTTP %1。").arg(httpStatus)
: QStringLiteral("后端错误HTTP %1%2").arg(httpStatus).arg(detail);
return false;
}
if (raw.isEmpty()) {
outError = QStringLiteral("后端返回空数据。");
return false;
}
outPngBytes = raw;
return true;
}
} // namespace core