zoukankan      html  css  js  c++  java
  • QNetworkAccessManager使用的简单封装

    实现对QNetworkAccessManager使用方式的简单封装类:HttpServer

    增加:

    1. 使用QEventLoop实现同步请求
    2. 异步请求可以传一个QVariant参数
    3. 可以设置超时时间
    

    限制:

    1.只能简单的使用put/post方法
    2.post 固定参数 ContentTypeHeader == application/json
    3.put 固定参数 ContentTypeHeader == application/x-www-form-urlencoded
    4.除上述参数外,其他参数都是默认设置
    4.没有考虑https协议
    

    使用方式:

    1. 使用factory函数获取类指针,异步调用可以设置自定义参数,会传给slot函数
    2. 如果异步调用,需连接signal和slot函数,使用setConnectTo可以方便连接参数最多的signal,slot函数
    3. 调用put/post相关函数

    例子:
    异步:

    // 调用
    QString url = "http://192.168.1.1:8080/XXX";
    QString data = "{}";
    QVariant param = 100;
    HttpServer *http = HttpServer::factory(this, param);
    http->setConnectTo(this);
    http->postRequest(url, data);
    
    .................................
    
    // slot函数
    void XXX::finished(QNetworkReply *reply, QVariant param, bool timeout)
    {
    	int myParam = param.toInt();
    	int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    	QString json = QTextCodec::codecForName("UTF-8")->toUnicode(reply->readAll());
    	reply->deleteLater();
    }
    

    同步:

    HttpServer *http = HttpServer::factory(this);
    bool timeout;
    auto *reply = http->postRequestSyn(url, data, &timeout);
    
    if(!timeout) {
    	int httpCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    	QString json = QTextCodec::codecForName("UTF-8")->toUnicode(reply->readAll());
    }
    reply->deleteLater();
    http->deleteLater();
    

    头文件:

    #ifndef HTTPSERVER_H
    #define HTTPSERVER_H
    
    #include <QObject>
    #include <QScopedPointer>
    #include <QtNetwork/QNetworkAccessManager>
    #include <QtNetwork/QNetworkReply>
    #include <QtNetwork/QNetworkRequest>
    #include <QTimer>
    
    class HttpServer : public QObject
    {
        Q_OBJECT
    public:
    	static HttpServer *factory(QObject *parent = 0, QVariant parameter = QVariant());
    	static HttpServer *factory(QVariant parameter = QVariant());
    
    	// 异步 get 请求
    	// param timeout 设置超时,结果作为槽函数实参
        void getRequest(const QString& url, bool timeout = false, long time = WAIT_TIME);
    
        // 同步 get 请求
    	// param timeout 指针不为0时进行超时设置,并且,接收是否超时结果
        QNetworkReply *getRequestSyn(const QString& url, bool *timeout = 0, long time = WAIT_TIME);
    
    	// 异步 post 请求,data 为 json
    	// param timeout 设置超时,结果作为槽函数实参
    	void postRequest(const QString& url, const QString &data, bool timeout = false, long time = WAIT_TIME);
    
    	// 同步 post 请求,data 为 json
    	// param timeout 指针不为0时进行超时设置,并且,接收是否超时结果
    	QNetworkReply *postRequestSyn(const QString& url, const QString &data, bool *timeout = 0, long time = WAIT_TIME);
    
    	// 异步请求时设置信号接收对象,三参数信号
    	// 也可用QObject::connect自定义接收对象和其他slot函数
    	void setConnectTo(QObject *receiver);
        
    signals:
    	// 可以通过setConnectTo连接
        void finished(QNetworkReply *reply, QVariant param, bool isTimeout);
    	// 自己连接
    	void finished(QNetworkReply *reply, QVariant param);
    	void finished(QNetworkReply *reply, bool isTimeout);
    	void finished(QNetworkReply *reply);
    
    private slots:
        void finished();
        void timeOut();
    
    private:
    	HttpServer(QObject *parent = 0,  QVariant parameter = QVariant());
    
        void get(const QString& url);
        void get_timeout(const QString& url, QTimer *timer, long time);
        QNetworkReply *get_syn(const QString& url);
        QNetworkReply *get_syn_timeout(const QString& url, bool *timeout, long time);
    
    	void post(const QString& url, const QString &data);
    	void post_timeout(const QString& url, const QString &data, QTimer *timer, long time);
    	QNetworkReply *post_syn(const QString& url, const QString &data);
    	QNetworkReply *post_syn_timeout(const QString& url, const QString &data, bool *timeout, long time);
    
        QNetworkRequest get_request(const QString& url);
    	QNetworkRequest post_request(const QString& url);
    	QByteArray post_data(const QString &data);
    
    	QNetworkReply *HttpServer::syn_timeout(QNetworkReply *reply, bool *isTimeout, long time);
    	QNetworkReply *HttpServer::syn(QNetworkReply *reply);
    
    	void emitSignals(QNetworkReply *reply, QVariant param, bool isTimeout);
    
        QScopedPointer<QNetworkAccessManager> mManager;
        QScopedPointer<QTimer> mTimer;
        QNetworkReply *mReply;
        QVariant mParam;
    
    	enum {
    		WAIT_TIME = 10000
    	};
    };
    
    #endif // HTTPSERVER_H
    
    

    实现文件:

    #include <QEventLoop>
    #include <QTextCodec>
    
    #include "httpserver.h"
    
     HttpServer *HttpServer::factory(QObject *parent,  QVariant parameter)
    {
    	return new HttpServer(parent, parameter);
    }
    
    HttpServer *HttpServer::factory( QVariant parameter)
    {
    	return new HttpServer(0, parameter);
    }
    
    HttpServer::HttpServer(QObject *parent,  QVariant parameter)
        :QObject(parent)
        ,mParam(parameter)
        ,mReply(nullptr)
    {
        mManager.reset(new QNetworkAccessManager);
        mTimer.reset(new QTimer);
    
        connect(mTimer.data(), SIGNAL(timeout()), this, SLOT(timeOut()));
    }
    
    void HttpServer::setConnectTo(QObject *receiver)
    {
    	connect(this, SIGNAL(finished(QNetworkReply *, QVariant, bool)), receiver, SLOT(finished(QNetworkReply *, QVariant, bool)));
    }
    
    void HttpServer::getRequest(const QString& url, bool timeout, long time)
    {
        if(timeout)
            get_timeout(url, mTimer.data(), time);
        else
            get(url);
    }
    
    QNetworkReply *HttpServer::getRequestSyn(const QString& url, bool *timeout, long time)
    {
        if(timeout)
            return get_syn_timeout(url, timeout, time);
        else
            return get_syn(url);
    }
    
    void HttpServer::postRequest(const QString& url, const QString &data, bool timeout, long time)
    {
    	if(timeout)
    		post_timeout(url, data, mTimer.data(), time);
    	else
    		post(url, data);
    }
    
    QNetworkReply *HttpServer::postRequestSyn(const QString& url, const QString &data, bool *timeout, long time)
    {
    	if(timeout)
    		return post_syn_timeout(url ,data, timeout, time);
    	else
    		return post_syn(url, data);
    }
    
    void HttpServer::finished()
    {
        mTimer->stop();
    
        emitSignals(mReply, mParam, false);
    
        this->deleteLater();
    }
    
    void HttpServer::timeOut()
    {
        mTimer->stop();
    
        emitSignals(mReply, mParam, true);
        disconnect(mReply, SIGNAL(finished()), this, SLOT(finished()));
    
        this->deleteLater();
    }
    
    void HttpServer::get(const QString& url)
    {
        mReply = mManager->get(get_request(url));
        connect(mReply, SIGNAL(finished()), this, SLOT(finished()));
    }
    
    void HttpServer::get_timeout(const QString& url, QTimer *timer, long time)
    {
        get(url);
        timer->start(time);
    }
    
    QNetworkReply *HttpServer::get_syn_timeout(const QString& url, bool *isTimeout, long time)
    {
    	QNetworkReply *reply = mManager->get(get_request(url));
    	return syn_timeout(reply, isTimeout, time);
    }
    
    QNetworkReply *HttpServer::get_syn(const QString& url)
    {
        QNetworkReply *reply = mManager->get(get_request(url));
    	return syn(reply);
    }
    
    void HttpServer::post(const QString& url, const QString &data)
    {
    	mReply = mManager->post(post_request(url), post_data(data));
    	connect(mReply, SIGNAL(finished()), this, SLOT(finished()));
    }
    
    void HttpServer::post_timeout(const QString& url, const QString &data, QTimer *timer, long time)
    {
    	post(url, data);
    	timer->start(time);
    }
    
    QNetworkReply *HttpServer::post_syn(const QString& url, const QString &data)
    {
    	QNetworkReply *reply = mManager->post(post_request(url), post_data(data));
    	return syn(reply);
    }
    
    QNetworkReply *HttpServer::post_syn_timeout(const QString& url, const QString &data, bool *isTimeout, long time)
    {
    
    	QNetworkReply *reply = mManager->post(post_request(url), post_data(data));
    	return syn_timeout(reply, isTimeout, time);
    }
    
    QNetworkReply *HttpServer::syn(QNetworkReply *reply)
    {
    	QEventLoop loop;
    	connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    
    	loop.exec();
    
    	return reply;
    }
    
    QNetworkReply *HttpServer::syn_timeout(QNetworkReply *reply, bool *isTimeout, long time)
    {
    	QEventLoop loop;
    	connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    
    	QTimer timer;
    	timer.setInterval(time);
    	timer.setSingleShot(true);
    	connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    
    	timer.start();
    	loop.exec();
    
    	if (timer.isActive()) {
    		timer.stop();
    		*isTimeout = false;
    		return reply;
    	} else {
    		disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    		*isTimeout = true;
    		return reply;
    	}
    }
    
    QNetworkRequest HttpServer::get_request(const QString& url)
    {
        QNetworkRequest request;
        request.setUrl(QUrl(url));
        request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
        return request;
    }
    
    QNetworkRequest HttpServer::post_request(const QString& url)
    {
    	QNetworkRequest request;
    	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    	request.setUrl(QUrl(url));
    	return request;
    }
    
    QByteArray HttpServer::post_data(const QString &data)
    {
    	QByteArray postData;
    	postData.append(QTextCodec::codecForName("UTF-8")->fromUnicode(data));
    	return postData;
    }
    
    void HttpServer::emitSignals(QNetworkReply *reply, QVariant param, bool isTimeout)
    {
    	emit finished(reply, param, isTimeout);
    	emit finished(reply, param);
    	emit finished(reply, isTimeout);
    	emit finished(reply);
    }
    
    
  • 相关阅读:
    Linux下SVN(Subversion)自动启动脚本
    Linux安装SVN
    【转】utf-8的中文是一个汉字占三个字节长度
    24-《分布式系统架构的本质》系列04——分布式系统关键技术:全栈监控
    23-《分布式系统架构的本质》系列03——分布式系统的技术栈
    22-《分布式系统架构的本质》系列02——从亚马逊的实践,谈分布式系统的难点
    由 leetcode 136. Single Number 引出的异或总结
    【工具软件】-Beyond Compare4 试用到期
    01-更新软件源
    01-程序员也要会项目管理
  • 原文地址:https://www.cnblogs.com/kohlrabi/p/7095238.html
Copyright © 2011-2022 走看看