gpt4 book ai didi

c++ - 删除 QNetworkReply 的最佳方法是什么?

转载 作者:行者123 更新时间:2023-11-28 05:24:39 25 4
gpt4 key购买 nike

我正在使用 OpenEmbedded 项目的 Qt5 Embedded 层编写嵌入式 RESTful API 客户端。我希望我的客户端能够发送一个简单的异步请求来通知我的服务器正在发生的事情,另一种情况是我的客户端需要从服务器同步数据。

为此,我编写了两个函数,一个用于发送请求,另一个用于获取响应。所以如果我不关心响应,我只使用第一个。

为了能够使用第二个响应,我使用 QNetworkReply * 作为我类(class)的成员。为了让 QNetworkReply 保持事件状态,我还将 QNetworkAccessManager 设置为我类(class)的成员。

#include <QtNetwork>

class ApiClient : public QObject
{
Q_OBJECT

public:

ApiClient(QObject *parent = 0);

private:

QString host;
QString key;
quint32 replyTimeout;
QNetworkAccessManager manager;
QNetworkReply *reply;

void sendRequest(const QString &method, const QVariantMap &params = QVariantMap());
QVariantMap getResponse() const;
};

apiclient.cpp 文件:

#include "apiclient.h"

ApiClient::ApiClient(QObject *parent) : QObject(parent)
{

}

void ApiClient::sendRequest(const QString &method, const QVariantMap &params)
{
QUrl url(QString("%1/%2/").arg(host).arg(method));

QUrlQuery query;
query.addQueryItem("key", key);

if (!params.empty())
{
QMapIterator<QString, QVariant> it(params);
while (it.hasNext())
{
it.next();
query.addQueryItem(it.key(), it.value().toString());
}
}

url.setQuery(query);
qDebug() << "url: " << url.toString();

reply = manager.get(QNetworkRequest(url));
}

QVariantMap ApiClient::getResponse() const
{
if (!reply)
{
qFatal("No request sent!");
}

QTimer timer;
timer.setSingleShot(true);

QEventLoop loop;
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
timer.start(replyTimeout);
loop.exec();

if (timer.isActive())
{
timer.stop();

if (reply->error())
{
qFatal("Wrong reply!");
}

int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (code != 200)
{
qFatal("Invalid server response!");
}

QJsonDocument result = QJsonDocument::fromJson(reply->readAll());

if (result.isNull())
{
qFatal("Invalid JSON!");
}

reply->deleteLater();
return result.object().toVariantMap();
}

disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
reply->abort();
reply->deleteLater();
return QVariantMap();
}

这是继续进行的好方法吗?当发出其他信号(即 error()、sslErrors() 等)时,我应该如何管理 QNetworkReply 指针?

最佳答案

QNetworkReply 将始终发出 finished(),即使发生错误也是如此。

deleteLater() 甚至可以在连接到该信号的插槽中调用,因此该部分应该没问题。

但我建议研究一种更异步的处理请求的方法,嵌套事件循环,如 getResponse() 中的 on 可以导致“有趣”的行为,因为您基本上可以得到进入单线程程序中的重入情况。

关于c++ - 删除 QNetworkReply 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40803530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com