QNetworkAccessManager实现可手动中断和超时机制的异步Http网络接口

文章目录


前言

Qt中的网络访问 API 是围绕 QNetworkAccessManager 对象构建的,该对象保存它发送的请求的通用配置和设置。因此实现Http请求必然需要使用QNetworkAccessManager 来开发。
需要注意的是:QNetworkAccessManager 是基于 QObject 的,所以只能在它所属的线程中使用。

接口实现

//发送请求结构,仅供参考
class PostPackge
{
public:
    QString postPath;
    QJsonObject postBody;
    bool isQuery = false; 
    int timeOut = 120000; //ms
    QNetworkRequest request;
};
//请求数据返回结构,仅供参考
class HttpResultPackge
{
public:
    int httpCode = 0;
    QString httpErrorString;
    QByteArray httpData;
};
//......
QString CYapiInterface::postDataToServerAsync_packge(const PostPackge& postPackge,
                                                     const std::function<void(const HttpResultPackge& resultPackge)> &callBack)
{
    //机制
    QSharedPointer<HttpResultPackge> resultPackge(new HttpResultPackge);
    QString uuid = QUuid::createUuid().toString(QUuid::WithoutBraces);
    //请求管理
    QNetworkAccessManager *netAm = new QNetworkAccessManager();
    QNetworkConfiguration netConfig;
    netConfig.setConnectTimeout(5000); //socket连接请求超时设置
    netAm->setConfiguration(netConfig);
    connect(netAm, &QNetworkAccessManager::finished, this, [this, resultPackge, callBack](QNetworkReply *amReply){
        getHttpResult(resultPackge.data(), amReply);

        callBack(*resultPackge);

        sender()->deleteLater();
    });
    //发送请求
    QNetworkReply *reply = netAm->post(postPackge.request, QJsonDocument(postPackge.postBody).toJson());
    reply->setParent(netAm);
    //超时开始计时
    QTimer *timer = new QTimer(netAm);
    connect(timer, &QTimer::timeout, reply, [reply, resultPackge](){
        if(reply->isRunning()){
            resultPackge->httpCode = QNetworkReply::TimeoutError;
            resultPackge->httpErrorString = QStringLiteral("请求超时");
            reply->close(); //close
        }
    });
    timer->start(postPackge.timeOut);
    //中断机制,仅读操作能够取消
    connect(this, &CYapiInterface::stopQuery, reply, [reply, resultPackge, uuid](const QString& abortUuid, const QString &reason){
        if(reply->isRunning()){
            if(abortUuid == uuid){
                resultPackge->httpCode = QNetworkReply::OperationCanceledError;
                resultPackge->httpErrorString = reason;

                reply->close();
            }
        }
    }, Qt::QueuedConnection);


    return uuid;
}

1.超时机制:利用QTimer定时,在到达设置时间后请求数据还未返回,则会中断请求。
2.中断机制:在请求发送后生成一条uuid并返回,外部调用者可根据该uuid中断请求,但是推荐只能使用查询相关的请求,不然可能会有意料之外的问题出现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值