文章目录
🌟1.概述
本文将基于Qt框架,讲解如何实现一个高效的HTTP客户端,并分析其核心代码实现原理。
Qt 提供了 QNetworkAccessManager 作为HTTP请求的核心组件,同时结合 QNetworkRequest 和 QNetworkReply,可以完成基本的HTTP通信。此外,为了提高并发处理能力,我们还会结合 ThreadPool 对请求的响应进行异步管理。
🌟2.代码结构概览
该HTTP客户端主要由以下几个核心组件组成:
- Http_Api_Manager:对外提供API调用的管理类,封装业务逻辑。
- Http_Request_Manager:具体负责发送HTTP请求。
- ThreadPool:线程池,用于异步处理请求,提高并发能力。
- TestWindow:测试类,用于模拟多次请求,测试出http请求的性能数据。
🌟3.代码解析
🌸Http_Api_Manager - API管理类
class Http_Api_Manager : public QObject
{
Q_OBJECT
struct ApiResponse {
// 通用响应数据结构解析,根据自定义响应报文解析
int code;
QString message;
QJsonValue data;
static ApiResponse fromJson(const QJsonDocument& doc);
};
public:
static Http_Api_Manager* getInstance();
// 测试API方法,可以考虑抽象出基类请求,外部调用公共接口,内部进行API类型区分
void updateAllVoteItem(const QString &userGuid, const QString &conferenceGuid, int pageNum, int pageSize, int requestIndex = -1);
signals://响应处理完毕信号
void allVoteItemUpdated(bool success,int index = 0);
void requestError(const QString& errorMessage);
private:
static Http_Api_Manager* instance;//单例
std::unique_ptr<ThreadPool> m_threadPool;//线程池
class Private;//声明私有类,将具体实现隐藏
std::unique_ptr<Private> d;//指向私有实现的指针
private:
explicit Http_Api_Manager(QObject *parent = nullptr);
~Http_Api_Manager();
// 基础JSON解析函数,将业务响应处理函数作为传参回调
void processResponse(const QByteArray &response,
std::function<void(const QJsonDocument&)> handler);
// 业务响应处理函数
void processVoteListResponse(const QJsonDocument& doc,const int &requestIndex = -1);
};
将API管理类实现为单例,方便全局调用以及对HTTP请求的管理。新增接口只需实现具体的请求函数、请求响应的业务处理函数以及处理完毕的信号函数。 对于响应的业务处理会放入子线程异步执行。
//具体的API请求函数
void Http_Api_Manager::updateAllVoteItem(const QString &userGuid, const QString &conferenceGuid, int pageNum, int pageSize, int requestIndex)
{
//查询传参
QMap<QString, QString> queryParams = {
{
"guid", conferenceGuid}, {
"pageNum", QString::number(pageNum)}, {
"pageSize", QString::number(pageSize)} };
//封装一个请求任务
Http_Request_Task task(Http_Request_Task::GET, "/api/client/voting/findVotingStatisticList", queryParams);
//调用Http_Request_Manager的公共接口,并传入响应处理回调函数
Http_Request_Manager::getInstance()->sendRequest(task, [this, requestIndex](const QByteArray& response) {
m_threadPool