Skip to content

Commit

Permalink
合并网路库线程,删除pack线程
Browse files Browse the repository at this point in the history
  • Loading branch information
jice1001 committed Aug 22, 2016
1 parent 3d8dc57 commit 9719d52
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 109 deletions.
Binary file modified doc/netlib.tar.gz
Binary file not shown.
198 changes: 89 additions & 109 deletions doc/服务器消息流动.txt
Original file line number Diff line number Diff line change
@@ -1,109 +1,89 @@
��ServerΪ������������Ϣ���̣������ͻ�����Ϣ--->����������������Ϣ--->�ͻ������̡�
��������ĸ��̣߳�
accept_���������̣߳�
receive_���������̣߳��߳��ڿ���epoll_watch������EPOLLIN�¼�
send_���������̣߳��߳��ڿ���epoll_watch������EPOLLOUT�¼�
pack_�����Ϣ�̣߳�
�����������ݽṹ����������svc����
Object_Po0l<Server_Svc, Spin_Lock> svc_static_list_ ���svc���б�������client��server�����Ӷ�����������
Svc_Static_List<Server_Svc *, Spin_Lock> svc_pool_ svc���ڴ������

Socket���̼�飺
�ͻ��ˣ�
ͨ��socket��������socketfd��connect������ip��port�����ӳɹ��󣬿�ͨ��socketfd����read/write�����������ͨ�š�
����ˣ�
ͨ��socket��������listenfd��bind��Ӧ�Ķ˿�/ip��Ȼ��listen���ȴ��пͻ������ӡ�
���пͻ�����������ʱ��ͨ��accept�������ӣ����ظ�connfd��Ȼ�����ͨ��connfd����read/write����ͻ��˽���ͨ�š�

��Ϣ�������̣�
1����������
Accept�߳������󣬻���run_handler�����������server_listen���м������ӣ��пͻ������ӵ���ʱ�򣬵���server_accept���ܸ����ӣ�
Ȼ�����accept_svc�������Ӻ��svc����svc�浽svc_static_list_���棬
Ȼ�����register_recv_handler����svcע�ᵽreceiver�̵߳�epoll���棬
����register_send_handler����svcע�ᵽsender�̵߳�epoll���棬�ȴ����ܺͷ������ݡ�
�������£�
Accept::thread_create->run_handler->server_listen->server_accept->
Server_Accept::accept_svc->
Svc_Static_List::record_svc->
Server_Svc::register_recv_handler->register_send_handler

2����������
Receive�߳������epoll_watch�ڼ�����EPOLLIN�¼��󣬻ᴥ��Event_Hander��handle_input�¼���
��ΪSvc�̳�Event_Handler�࣬receive��epoll�����˸�svc�������Svc��recv_data������
��socket��������ȡ��������Block_Bufferͨ��push_recv_block�����ŵ�Svc���recv_block_list_����
Ȼ�����recv_handler�������ӵ�cid_ͨ��push_packing_cid�ŵ�Packer�̵߳�packing_list_����,��packer�߳�ѭ������
�������£�
Server_Svc::register_recv_handler->
Receive::register_svc->(reactor_->add(svc, Epoll_Watcher::EVENT_INPUT))
Epoll_Watcher::watcher_loop->handle_input->
Svc::revc_data->push_recv_block->recv_block_list_(�ýṹ�洢���յ�������BlockBuffer)
Server_Svc::recv_handler->
Server_Packer::push_packing_cid->Stream_Packer::packing_list_(�ýṹ�洢���յ����ݵ�cid)

3���������
Pack�߳��ڴ�������run_handler��������ѭ������process_packing_list���н����
��packing_list_����ȡ�����µ�cid���ҵ���Ӧ��SvcȻ�����svc��pack_recv_data���н����ѭ����recv_block_list_����ȡ������
Ȼ����д������������ͨ��packed_data_handler�ŵ�Server��block_list_���档
�������£�
Pack:thread_create->run_handler->process->process_packing_list->
Svc::pack_recv_data->Svc::recv_block_list_(����������б���ѭ��ȡ�������д���)
Server_Pack::packed_data_handler->
Server::block_list_

4�����ݷŵ��߼��̣߳������߼�����
��Game_Gate_ServerΪ����������ʱ�򣬻Ὺ��һ��ѭ����ѭ����Server��block_list_��ȡ���ݣ�ͨ��
GAME_MANAGER->push_game_gate_data(buf)�ŵ�Game_Manager��game_gate_data_list_�С�
Game_Manager�߳��ڴ�����ͨ��run_handler����process_list�������ݴ�����ѭ����game_gate_data_list_ȡ��Block_Buffer��
Ȼ�����Game_Client_Message��process_block������Ϣ��������Block_Buffer�������msg_id������msg_id���в�ͬ�ĺ����߼�������
�������ͨ��gate���ظ��ͻ���,���ˣ��ͻ��˷�������������Ϣ������ϡ�
�������£�
Game_Gate_Server:thread_create->run_handler->process_list->
Game_Manager::push_game_gate_data

Game_Manager::thread_create->run_handler->process_list->game_gate_data_list_.pop_front
Game_Client_Messager::process_block->�߼����ܴ���

5����������
����������Ҫ���͸��ͻ���ʱ�򣬵���Gate_Manger�����send_to_client��Ȼ�����ݷ��͸�send_��
�浽append_list_���棬��send_�߳�����epoll�����Ķ�ʱ��ʱ�䵽��ʱ�򣬻����send��hanlder_timeout������
�ú����ȵ���append_send_block��append_list_��������ݴ��͵�svc��send_block_list_���棬
Ȼ��ͨ��svc��send_data�����ݷ��͵�socket��������Ȼ��ͨ�����緢�͸��ͻ��ˡ�
�������£�
Game_Manager::send_to_client->
Send::push_data_block_with_len->
Svc::append_list_(�ýṹ��Ŵ����͵�Block_Buffer)

Send:thread_create->run_handler->register_self_timer->
Epoll_Watcher::watcher_loop->
Send::handle_timeout->append_send_block->
Svc::push_send_block->send_block_list_(ѭ����list��ȡ������ͨ��socket����)
Svc::send_data

6�����ӹر�����
Receive����ע���˸�io������ʱ�¼�����epoll���������¼�ʱ��˵���Ѿ��޷����ӵ��ͻ��ˣ��������������رո����ӣ�
���ȵ���epoll_watch�����handle_timeout������Ȼ����õ�svc�������handle_close������
Ȼ�����Server_Svc�����close_handler���ú�����֪ͨReceive���ߵ�cid���ŵ�drop_list_���棬
��Receive��epoll����drop_list_ʱ���ֻ�ͨ��Server_Receive��drop_handler����֪ͨSend�������ߣ�
�ŵ�Send��drop_list_���棬Send��ʱ��������ʱ���ֻ�ͨ��Server_Send��drop_handler����֪ͨPack�������ߣ�
�����Server_Pack��drop_handler���棬�����svc���ر�fd��֪ͨGame_Manger��
ͨ��Game_Manger��process_drop_cid��Game_Player���ߡ�
�������£�
Receive::init->Epoll_Watcher::WITH_IO_HEARTBEAT
Epoll_Watcher::watch_loop->handle_timeout->
svc:handle_close->
Server_Svc::close_handler->
Receive::push_drop->drop_list->
Server_Receive::drop_handler->
Send::push_drop_->
Server_Send:drop_handler->
Pack::push_drop->drop_list_
Server_Pack::drop_handler->
Game_Manager::push_drop_cid->drop_cid_list_->
Server::svc_static_list_-> erase_svc


����cid
cid�Ƿ��������ɵ�һ��id,ÿ���ͻ������ӵ��������󣬶�������һ��Ψһ��cid���������ҿͻ��˵�����Svc,
cid������svc���У���Svc::recv_dataʱ�򣬽�cidд�뵽BlockBuffer��ͷ�� ��Ȼ����Ϣ����������߼��㴦��
����������Ҫ��ͻ��˷�����Ϣʱ����Svc::send_data�У��Ὣcidȥ�������������ݷ����ͻ��ˣ������ڿͻ���
�ͷ�������ͨ����Ϣ�У��Dz���cid��
以Server为例,讲解下消息流程,包括客户端消息--->服务器,服务器消息--->客户端
该类包括三个线程:
accept_接受连接线程,
receive_接收数据线程,线程内开启epoll_watch,监听EPOLLIN事件
send_发送数据线程,线程内开启epoll_watch,监听EPOLLOUT事件
包含两个数据结构,用来处理svc连接
Object_Po0l<Server_Svc, Spin_Lock> svc_static_list_ 存放svc的列表,所有client到server的连接都保存在这里
Svc_Static_List<Server_Svc *, Spin_Lock> svc_pool_ svc的内存管理类

Socket流程简介:
客户端:
通过socket函数创建socketfd,connect服务器ip,port,连接成功后,可通过socketfd进行read/write与服务器进行通信。
服务端:
通过socket函数创建listenfd,bind相应的端口/ip,然后listen,等待有客户端连接。
当有客户端连接上来时候,通过accept接受连接,返回个connfd,然后可以通过connfd进行read/write,与客户端进行通信。

消息流动过程:
1、接受连接
Accept线程启动后,会在run_handler函数里面调用server_listen进行监听连接,有客户端连接到达时候,调用server_accept接受该连接,
然后调用accept_svc处理连接后的svc,将svc存到svc_static_list_里面,
然后调用register_recv_handler将该svc注册到receiver线程的epoll里面,
调用register_send_handler将该svc注册到sender线程的epoll里面,等待接受和发送数据。
流程如下:
Accept::thread_create->run_handler->server_listen->server_accept->
Server_Accept::accept_svc->
Svc_Static_List::record_svc->
Server_Svc::register_recv_handler->register_send_handler

2、接收数据
Receive线程里面的epoll_watch在监听到EPOLLIN事件后,会触发Event_Hander的handle_input事件,
因为Svc继承Event_Handler类,receive的epoll监听了该svc,会调用Svc的handle_input函数,
从socket缓冲区读取到的数据Block_Buffer通过push_recv_block函数放到Svc类的recv_block_list_里面
然后调用Svc_Handler的handler_pack函数进行解包,最后将buffer放到server的block_list_
流程如下:
Server_Svc::register_recv_handler->
Receive::register_svc->(reactor_->add(svc, Epoll_Watcher::EVENT_INPUT))
Epoll_Watcher::watcher_loop->Svc::handle_input->
push_recv_block->recv_block_list_(该结构存储接收到的数据BlockBuffer)
Svc_Hander->handle_pack->Server::block_list_

3、数据处理
以Game_Gate_Server为例,在启动时候,会开启一个循环,循环从Server的block_list_中取数据,通过
GAME_MANAGER->push_game_gate_data(buf)放到Game_Manager的game_gate_data_list_中。
然后js脚本线程启动后,会不断的从game_gate_data_list_里面pop消息进行逻辑处理
流程如下:
Game_Gate_Server:thread_create->run_handler->process_list->
Game_Manager::push_game_gate_data
game_server.js::pop_game_gate_msg_object->process_game_gate_msg

4、发送数据
当有数据需要发送给客户端时候,调用Gate_Manger里面的send_to_client,然后将数据发送给send_,
存到append_list_里面,当send_线程里面epoll监听的定时器时间到期时候,会调用send的hanlder_timeout函数,
该函数先调用append_send_block将append_list_里面的数据传送到svc的send_block_list_里面,
然后通过svc的handle_send将数据发送到socket缓冲区,然后通过网络发送给客户端。
流程如下:
Game_Manager::send_to_client->
Send::push_data_block_with_len->
Svc::append_list_(该结构存放待发送的Block_Buffer)

Send:thread_create->run_handler->register_self_timer->
Epoll_Watcher::watcher_loop->
Send::handle_timeout->append_send_block->
Svc::push_send_block->send_block_list_(循环从list中取出数据通过socket发送)
Svc::handle_send

5、连接关闭流程
Receive里面注册了个io心跳超时事件,当epoll监听到该事件时候,说明已经无法连接到客户端,服务器会主动关闭该连接,
首先调用epoll_watch里面的handle_timeout函数,然后调用到svc类里面的handle_close函数,
然后调用Server_Svc里面的close_handler,该函数会通知Receive掉线的cid,放到drop_list_里面,
在Receive的epoll处理drop_list_时候,又会通过Server_Receive的drop_handler函数通知Send处理掉线,
放到Send的drop_list_里面,Send超时函数处理时候,在Send的drop_handler里面,会回收svc,关闭fd,通知Game_Manger,
通过Game_Manger的process_drop_cid让Game_Player掉线。
流程如下:
Receive::init->Epoll_Watcher::WITH_IO_HEARTBEAT
Epoll_Watcher::watch_loop->handle_timeout->
svc:handle_close->
Server_Svc::close_handler->
Receive::push_drop->drop_list->
Server_Receive::drop_handler->
Send::push_drop_->
Server_Send:drop_handler->
Game_Manager::push_drop_cid->drop_cid_list_->
Server::svc_static_list_-> erase_svc

关于cid
cid是服务器生成的一个id,每个客户端连接到服务器后,都会生成一个唯一的cid,用来查找客户端的连接Svc,
cid保存在svc类中,在Svc::handle_input时候,将cid写入到BlockBuffer的头部,然后消息组包,丢到逻辑层处理
当服务器需要向客户端发送消息时候,在Svc::handle_send中,会将cid去掉,将包的内容发给客户端,所以在客户端
和服务器的通信消息中,是不带cid的

0 comments on commit 9719d52

Please sign in to comment.