目录
1. 数据包的处理过程
见图 http://baike.corp.taobao.com/index.php/File:Easy%E6%95%B0%E6%8D%AE%E6%B5%81%E7%A8%8B%E5%9B%BE.png
2. 主要数据类型(src/io/easy_io_struct.h中的数据结构)
3. 服务器端和客户端程序使用api的步骤
4. 主要io接口(src/io/文件夹)
5. include包(src/include/文件夹)
6. util包(src/util/文件夹)
1. 数据包的处理过程
1.1 服务器端调用过程
/**
* accept 事件处理
* 1. 为新连接创建一个easy_connection_t对象
* 初始化c->read_watcher = easy_connection_on_readable
* 初始化c->write_watcher = easy_connection_on_writable
* 初始化c->timeout_watcher = easy_connection_on_timeout_conn
* 2. accept请求
* 3. 调用easy_connection_on_readable
**/
void easy_connection_on_accept(struct ev_loop *loop, ev_io *w, int revents)
/**
* read事件处理
* 1. 第一次读或者上次读完整了, 新建一个easy_message_t
* 2. 从conn里读入数据
* 3. 调用easy_connection_do_request处理请求
*/
easy_connection_on_readable(struct ev_loop *loop, ev_io *w, int revents)
/**
* 处理请求
* 1. 对请求decode,返回packet
* 2. 创建easy_request_t,加入到m->request_list列表里
* 3. batch_process操作
* 4. 对request_list列表里的请求调用process进行处理
* 5. 1)对处理返回EASY_OK的,调用encode返回响应
* 2)处理返回EASY_AGAIN等待process中的回调函数,在回调函数中调用easy_request_do_reply
*/
int easy_connection_do_request(easy_message_t *m)
/**
* 在process中异步处理通过回调函数返回
* 1. 通过encode把 easy_request_t->packet里面的回复信息添加到easy_connection_t->output链里面
* 2. 调用easy_connection_write_socket把easy_connection_t->output链里面的数据写到socket里面
*/
easy_request_do_reply(easy_request_t *r)
图1 easy数据流程图
1.2 客户端调用过程
1.2.1 客户端发送请求步骤
/**
* 连接。
* 1. connect到服务器
* 2. 创建一个easy_connection_t对象,初始化easy_connection_t对象。
* 初始化c->read_watcher = easy_connection_on_readable
* 初始化c->write_watcher = easy_connection_on_writable
* 初始化c->timeout_watcher = easy_connection_on_timeout_conn
*/
easy_connection_t *easy_connection_connect_addr(easy_io_t *eio, easy_addr_t addrv, easy_io_handler_pt *handler)
/**
* write事件处理
* 1. 调用new_packet创建packet
* 2. 创建easy_session_t和packet
* 3. 调用easy_connection_send_session发送数据
*/
static void easy_connection_on_writable(struct ev_loop *loop, ev_io *w, int revents)
/**
* 1. 对easy_session_t进行easy_connection_sesson_build
* 在easy_connection_session_build里面对请求进行encode
* 2. 调用easy_connection_write_socket把encode好的数据写到socket里面
*/
int easy_connection_send_session(easy_session_t *s)
/**
* 1. 在easy_connection_sesson_build里面对请求进行encode
* 2. 以packet_id为key,把easy_session_t加入到c->send_queue哈希表里面
*/
void easy_connection_session_build(easy_session_t *s)
1.2.2 客户端接收响应步骤
/**
* read事件处理
* 1. 第一次读或者上次读完整了, 新建一个easy_message_t
* 2. 从conn里读入数据
* 3. 调用easy_connection_do_response处理响应
*/
easy_connection_on_readable(struct ev_loop *loop, ev_io *w, int revents)
/**
* 处理响应
* 1. 对服务器返回的响应进行decode操作
* 2. 通过获取的packet_id从c->send_queue哈希表中得到easy_session_t
* 2. 调用easy_session_process处理返回的响应
* 3. 如果客户端没有发送完请求,创建新的packet继续请求服务器
*/
static int easy_connection_do_response(easy_message_t *m)
/**
* 1. 对响应进行处理
*/
int easy_session_process(easy_session_t *s)
2 主要操作的类型
2.1
struct easy_io_handler_pt {
// 1.在服务器端,用于解析客户端请求。
// 2.在客户端端,用于解析服务器返回的响应
void* (*decode)(easy_message_t *m);
// 1.服务器端,packet是decode的输出,把数据封装后添加到output里
// 2.客户端端,用于封装new_packet创建的packet,然后填加到output里
int (*encode)(easy_buf_chain_t *output, void *packet);
easy_io_process_pt *process;
int (*batch_process)(easy_message_t *m);
int (*cleanup)(void *packet);
// 获取packet_id
uint64_t (*get_packet_id)(easy_connection_t *c, void *packet);//
int (*on_connect) (easy_connection_t *c); //
// 在销毁easy_connection_t的时候,释放掉easy_io_handler_pt包含的数据
int (*on_disconnect) (easy_connection_t *c);
// 创建用于请求的packet和easy_session_t
// easy_connection_send_session发送请求
int (*new_packet) (easy_connection_t *c); //
void *user_data, *user_data2; //
int is_uthread;
};
// 对应一个SOCKET连接
struct easy_connection_t {
struct ev_loop *loop;
easy_pool_t *pool; // 用于分配在connect存活周期对象的空间,easy_connection_t本身也由pool分配的
easy_pool_t *pbuf; // 用于创建packet easy_buf_t
easy_atomic_t ref; //
easy_io_thread_t *ioth; // 每个connect某一时刻在一个线程执行,connect满足一定要求是可以切换到其他线程执行,ioth用于保存线程的指针
easy_connection_t *next; // 没次accept会创建一个connetect,next指向下一个connect
easy_list_t conn_list_node; // 加入到ioth中connect list的节点
easy_hash_list_t client_list_node; // 用于client端
// file description
uint32_t default_message_len;
int fd;
easy_addr_t addr;
ev_io read_watcher; // 在client端是easy_connection_on_readable,server端是easy_connection_on_accept/easy_connection_on_readable
ev_io write_watcher; //
ev_timer timeout_watcher; //
easy_list_t message_list; // 用于保存easy_message_t的链表。接收请求/响应时会用到easy_message_t,保存一个或者多easy_request_t
easy_list_t server_session_list; // 用于保存easy_session_t的链表。easy_session_t是用于发送请求/响应的,每个easy_session_t只带一个easy_request_t
easy_buf_chain_t output; // 输出缓存链, output.pool = pbuf。
easy_io_handler_pt *handler; // 操作类型, 包括decode,encode, process, batch_process, on_connect等等
void *user_data; //
easy_hash_t