基于libevent的http接口封装(二)

一、定义请求事件和业务回调函数等数据结构

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);
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值