mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 09:20:52 +08:00
150 lines
4.5 KiB
C++
150 lines
4.5 KiB
C++
#pragma once
|
||
#include "acl_cpp/stream/aio_handle.hpp"
|
||
#include "acl_cpp/ipc/ipc_service.hpp"
|
||
#include "acl_cpp/http/http_header.hpp"
|
||
|
||
namespace acl {
|
||
|
||
class string;
|
||
|
||
/**
|
||
* HTTP 服务请求类,子类必须继承该类
|
||
*/
|
||
class ACL_CPP_API http_service_request : public http_header
|
||
{
|
||
public:
|
||
/**
|
||
* 构造函数
|
||
* @param domain {const char*} HTTP 服务器的域名(也可以是IP),非空
|
||
* 如果传入了空值,则会 fatal
|
||
* @param port {unsigned short} HTTP 服务端口
|
||
*/
|
||
http_service_request(const char* domain, unsigned short port);
|
||
|
||
/**
|
||
* 获得由构造函数输入的 domain
|
||
* @return {const char*} 永不为空
|
||
*/
|
||
const char* get_domain(void) const;
|
||
|
||
/**
|
||
* 获得由构造函数输入的 port
|
||
* @return {unsigned short}
|
||
*/
|
||
unsigned short get_port(void) const;
|
||
|
||
/**
|
||
* 当任务处理完毕或出错时,内部处理过程会自动调用 destroy 接口,
|
||
* 子类可以在该接口内进行一些释放过程,尤其当该对象是动态创建时,
|
||
* 子类应该在该函数内 delete this 以删除自己,因为该函数最终肯定
|
||
* 会被调用,所以子类不应在其它地方进行析构操作
|
||
*/
|
||
virtual void destroy(void) {}
|
||
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// 子类必须实现如此虚接口
|
||
|
||
/**
|
||
* 获得 HTTP 请求体数据,该函数会在请求过程中被循环调用,直到返回的数据对象
|
||
* 中的数据为空
|
||
* @return {const string*} 请求体结果数据,如果返回空指针或返回的缓冲区对象
|
||
* 的数据为空(即 string->empty()) 则表示 HTTP 请求体数据结束
|
||
* 注意:与其它函数不同,该虚接口是另外的子线程中被调用的,所以如果子类实
|
||
* 现了该接口,如果需要调用与原有线程具备竞争的资源时应该注意加锁保护
|
||
*/
|
||
virtual const string* get_body(void);
|
||
|
||
/**
|
||
* 当获得 HTTP 服务器的 HTTP 响应头时的回调接口
|
||
* @param addr {const char*} 与服务器之间的连接地址,格式:IP:PORT
|
||
* @param hdr {const HTTP_HDR_RES*} HTTP 响应头,该结构定义参见:
|
||
* acl_project/lib_protocol/include/http/lib_http_struct.h
|
||
*/
|
||
virtual void on_hdr(const char* addr, const HTTP_HDR_RES* hdr) = 0;
|
||
|
||
/**
|
||
* 当获得 HTTP 服务器的 HTTP 响应体时的回调接口,当 HTTP 响应体数据
|
||
* 比较大时,该回调会被多次调用,直到出错(会调用 on_error)或数据读完
|
||
* 时,该回调的两个参数均 0,当 data 及 dlen 均为 0 时,表明读 HTTP
|
||
* 响应体结束
|
||
* @param data {const char*} 某次读操作时 HTTP 响应体数据
|
||
* @param dlen {size_t} 某次读操作时 HTTP 响应体数据长度
|
||
* 注:如果 HTTP 响应只有头数据而没有数据体,则也会调用该函数通知用户
|
||
* HTTP 会话结束
|
||
*/
|
||
virtual void on_body(const char* data, size_t dlen) = 0;
|
||
|
||
/**
|
||
* 在 HTTP 请求或响应过程中如果出错,则会调用此接口,通知子类出错,
|
||
* 在调用此接口后
|
||
* @param errnum {http_status_t} 出错码
|
||
*/
|
||
virtual void on_error(http_status_t errnum) = 0;
|
||
protected:
|
||
virtual ~http_service_request(void);
|
||
private:
|
||
char* domain_;
|
||
unsigned short port_;
|
||
};
|
||
|
||
class aio_socket_stream;
|
||
|
||
class ACL_CPP_API http_service : public ipc_service
|
||
{
|
||
public:
|
||
/**
|
||
* 构造函数
|
||
* @param nthread {int} 如果该值 > 1 则内部自动采用线程池,否则
|
||
* 则是一个请求一个线程
|
||
* @param nwait {int} 当异步引擎采用 ENGINE_WINMSG 时,为了避免
|
||
* 因任务线程发送的数据消息过快而阻塞了主线程的 WIN32 消息循环,
|
||
* 在任务线程发送数据消息时自动休眠的毫秒数;对于其它异步引擎,
|
||
* 该值也可以用于限速功能
|
||
* @param win32_gui {bool} 是否是窗口类的消息,如果是,则内部的
|
||
* 通讯模式自动设置为基于 WIN32 的消息,否则依然采用通用的套接
|
||
* 口通讯方式
|
||
*/
|
||
http_service(int nthread = 1, int nwait = 1, bool win32_gui = false);
|
||
~http_service(void);
|
||
|
||
/**
|
||
* 应用调用此函数开始 HTTP 会话过程,由 http_service 类对象负责
|
||
* 向服务器异步发出 HTTP 请求,同时异步读取来自于 HTTP 服务器的响应
|
||
* @param req {http_service_request*} HTTP 请求类对象
|
||
*/
|
||
void do_request(http_service_request* req);
|
||
protected:
|
||
#ifdef WIN32
|
||
/**
|
||
* 基类虚函数,当收到来自于子线程的 win32 消息时的回调函数
|
||
* @param hWnd {HWND} 窗口句柄
|
||
* @param msg {UINT} 用户自定义消息号
|
||
* @param wParam {WPARAM} 参数
|
||
* @param lParam {LPARAM} 参数
|
||
*/
|
||
virtual void win32_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||
#endif
|
||
/**
|
||
* 基类虚函数,当有新连接到达时基类回调此函数
|
||
* @param client {aio_socket_stream*} 接收到的新的客户端连接
|
||
*/
|
||
virtual void on_accept(aio_socket_stream* client);
|
||
|
||
/**
|
||
* 基类虚函数,当监听流成功打开后的回调函数
|
||
* @param addr {const char*} 实际的监听地址,格式:IP:PORT
|
||
*/
|
||
virtual void on_open(const char*addr);
|
||
|
||
/**
|
||
* 基类虚函数,当监听流关闭时的回调函数
|
||
*/
|
||
virtual void on_close(void);
|
||
private:
|
||
char* addr_;
|
||
int nwait_;
|
||
aio_handle_type handle_type_;
|
||
};
|
||
|
||
} // namespace acl
|