一、定义请求事件和业务回调函数等数据结构
1.1 http请求类型
//http请求类型
enum Enum_HttpType
{
//get请求
HTTPTYPE_GET,
//post请求
HTTPTYPE_POST,
//download请求
HTTPTYPE_DOWNLOAD,
//upload请求
HTTPTYPE_UPLOAD
};
1.2 http请求结果
struct Struct_HttpResult
{
//请求结果
bool successed = true;
//请求code
int http_code;
//请求结果头
std::unordered_map<std::string, std::string> http_heads;
//请求结果数据
std::string http_result;
};
1.3 upload上传数据
struct Struct_MultiHttpPart
{
//上传数据类型枚举
enum Enum_PartAttribute
{
//文件类型
PART_FILE,
//文本类型
PART_TEXT,
};
//数据格式
std::string mime_type = "text/plain";
//数据
std::string value;
//数据类型
Enum_PartAttribute em_attribute = PART_TEXT;
};
1.4 业务回调函数
//http结果回调
typedef std::function<void(std::shared_ptr<Struct_HttpResult>)> HttpCallBack;
二、调用接口
这是一个单例类,方便外部的调用,对外提供get()、 post()、download()、upload()接口函数
2.1 get()函数第一个参数是请求url;第二个参数是业务回调函数;第三个参数是请求超时时间;第四个参数是请求头,这里提供了默认值,一般可忽略
2.2 post()函数第一个参数是请求url;第二个参数是请求数据;第三个参数是业务回调函数;第四个参数是请求超时时间;第五个参数是请求头,这里提供了默认值,一般可忽略
2.3 download()函数第一个参数是请求url;第二个参数是下载文件路径;第三个参数是业务回调函数;第四个参数是请求超时时间;第五个参数是请求头,这里提供了默认值,一般可忽略
2.4 upload()函数第一个参数是请求url;第二个参数是上传文件对象;第三个参数是业务回调函数;第四个参数是请求超时时间;第五个参数是请求头,这里提供了默认值,一般可忽略
2.5 m_count 定义了一共创建多少个libevebt服务,这里最好改成常量。
2.6 m_index用来做简单负载均衡用的,简单的说就是每次请求,都会根据m_index获取libevent服务,然后把m_index加1
#ifndef HTTPCLIENTIMPL_H
#define HTTPCLIENTIMPL_H
#include <vector>
#include "HttpClientCommon.h"
class HttpClientHelper;
class HttpClientImpl
{
public:
static HttpClientImpl &getInstance()
{
static HttpClientImpl s_instance;
return s_instance;
}
~HttpClientImpl();
void get(std::string http_url, HttpCallBack http_callback,
size_t timeout_second = 10,
std::unordered_map<std::string, std::string> headers = { {"Content-Type","application/x-www-form-urlencoded;charset=UTF-8"} });
void post(std::string http_url, std::unordered_map<std::string, std::string> datas, HttpCallBack http_callback,
size_t timeout_second = 10,
std::unordered_map<std::string, std::string> headers = { {"Content-Type","application/json;charset=UTF-8"} });
void download(std::string http_url, std::string download_path, HttpCallBack http_callback,
size_t timeout_second = 10,
std::unordered_map<std::string, std::string> headers = { {"Content-Type","application/x-www-form-urlencoded;charset=UTF-8"} });
void upload(std::string http_url, std::unordered_map<std::string, Struct_MultiHttpPart> http_parts, HttpCallBack http_callback,
size_t timeout_second = 10);
private:
HttpClientImpl();
void free_http();
std::shared_ptr<HttpClientHelper> http_helper();
size_t m_count = 5;
size_t m_index = 0;
std::vector<std::shared_ptr<HttpClientHelper>> m_http_helpers;
};
#endif
三、调用接口的实现
在构造函数中,创建服务,并等待每一个服务起来;析构函数中释放服务;http_helper()就是简单的负载均衡(哈哈~)
#include "HttpClientImpl.h"
#include "HttpClientHelper.h"
#include <WinSock2.h>
#include <event2\thread.h>
HttpClientImpl::HttpClientImpl()
{
evthread_use_windows_threads();
//加载套接字库
WSADATA wsaData;
int iRet = 0;
iRet = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iRet != 0)
{
return ;
}
if (2 != LOBYTE(wsaData.wVersion) || 2 != HIBYTE(wsaData.wVersion))
{
WSACleanup();
return ;
}
//起1个实例
for (size_t i = 0; i < m_count; ++i)
{
std::shared_ptr<HttpClientHelper> http_helper = std::make_shared<HttpClientHelper>();
http_helper->start();
while (!http_helper->is_start())
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
m_http_helpers.push_back(http_helper);
}
}
std::shared_ptr<HttpClientHelper> HttpClientImpl::http_helper()
{
if (m_index >= m_count)
{
m_index = 0;
}
if (m_count > 0)
{
return m_http_helpers[m_index++];
}
return nullptr;
}
HttpClientImpl::~HttpClientImpl()
{
free_http();
}
void HttpClientImpl::free_http()
{
if (m_http_helpers.size())
{
m_count = 0;
for (auto http_helper : m_http_helpers)
{
http_helper->stop();
while (http_helper->is_start())
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
WSACleanup();
m_http_helpers.clear();
}
}
void HttpClientImpl::get(std::string http_url, HttpCallBack http_callback, size_t timeout_second, std::unordered_map<std::string, std::string> headers)
{
auto http = http_helper();
if (http)
{
http->get(http_url, http_callback, timeout_second, headers);
}
}
void HttpClientImpl::post(std::string http_url, std::unordered_map<std::string, std::string> datas, HttpCallBack http_callback, size_t timeout_second, std::unordered_map<std::string, std::string> headers)
{
auto http = http_helper();
if (http)
{
http->post(http_url, datas, http_callback, timeout_second, headers);
}
}
void HttpClientImpl::download(std::string http_url, std::string download_path, HttpCallBack http_callback, size_t timeout_second, std::unordered_map<std::string, std::string> headers)
{
auto http = http_helper();
if (http)
{
http->download(http_url, download_path, http_callback, timeout_second, headers);
}
}
void HttpClientImpl::upload(std::string http_url, std::unordered_map<std::string, Struct_MultiHttpPart> http_parts, HttpCallBack http_callback, size_t timeout_second)
{
auto http = http_helper();
if (http)
{
http->upload(http_url, http_parts, http_callback, timeout_second);
}
}