revolver的核心部件庫core是基於revolver base之上進行封裝的,實現TCP連接管理、消息隱射管理、服務登記和感知 、IFrame框架和插件等。以下是core的模塊結構圖:
1 Core Packet
class CCorePacket : public CBasePacket
{
public:
void set_data(CBasePacket& packet, bool zlib = true);
void get_data(CBasePacket& packet);
...
protected:
//編碼解碼函數
virtual void Pack(BinStream& strm) const;
//解碼函數
virtual void UnPack(BinStream& strm);
...
public:
uint32_t server_id_; //服務器ID
uint8_t server_type_; //服務器類型,0表示客戶端
uint32_t msg_id_; //消息ID
uint8_t msg_type_; //消息類型,例如獨立的PING PONG消息,握手消息,應用層消息等
string data_; //消息內容
};
typedef enum PacketClass
{
CORE_HANDSHAKE, //TCP握手協議類型
CORE_REQUEST, //TCP消息載體類型
CORE_PING, //TCP心跳協議類型
CORE_MEDIA_SHELL,
CORE_ZLIB,
CORE_PONG
}PacketClass;
void CCorePacket::Pack(BinStream& strm) const
{
strm << server_id_ << server_type_ << msg_id_ << msg_type_ << data_;
}
UnPack的代碼實現:void CCorePacket::UnPack(BinStream& strm)
{
strm >> server_id_ >> server_type_ >> msg_id_ >> msg_type_ >> data_;
}
這連兩個函數主要是使用的Revolver Base中BinStream的<<和>>。具體細節可以查看對應的代碼。CorePacket打包成網絡字節序流代碼示例:BinStream strm;
strm << packet; //packet爲CorePacket實例
2 Connection和連接管理
class CConnection : public CEventHandler
{
public:
...
//事件接口
int32_t handle_input(BASE_HANDLER handle);
int32_t handle_output(BASE_HANDLER handle);
int32_t handle_close(BASE_HANDLER handle, ReactorMask close_mask);
int32_t handle_exception(BASE_HANDLER handle);
int32_t handle_timeout(const void *act, uint32_t timer_id);
//發起一條TCP連接
int32_t connect(const Inet_Addr& remote_addr);
int32_t connect(const Inet_Addr& src_addr, const Inet_Addr& dst_addr);
//關閉連接
void close();
//發送數據
int32_t send(CCorePacket& packet, bool no_delay = false);
int32_t send(const string& bin_stream);
...
protected:
...
CSockStream sock_stream_; //SOCKET 對象實例
SBuffer sbuffer_; //TCP發送BUFFER,解決報文發送分包問題
RBuffer rbuffer_; //TCP接收BUFFER,解決報文粘包和組包問題
BinStream istrm_; //接收的BinStream流對象
uint8_t server_type_; //0表示客戶端
uint32_t server_id_; //對端服務的server ID,如果是客戶端爲0
Inet_Addr remote_addr_; //遠端地址
};
在CConnection實現中,會處理CORE_HANDSHAKE CORE_PING CORE_PONG類型的消息,其中CORE_HANDSHAKE會對遠端服務做身份校驗。CORE_PING和CORE_PONG是用來做連接心跳維繫的,一般是1分鐘發送一次,如果連接超過4個發送週期沒有到對端任何報文,就會斷開此連接。#define SendDispathByID(packet, id)\
CONN_MANAGER()->send_dispatch_by_id(packet, id)
#define SendDispathByUDP(packet, id)\
CONN_MANAGER()->send_dispatch_by_udp(packet, id)
#define SendUDP(packet, addr)\
CONN_MANAGER()->send_udp(packet, addr)
#define SendTCP(packet, conn)\
CONN_MANAGER()->send_tcp(packet, conn)
如果本地服務要像遠端服務(server_id = 10)發送一個類型爲CCorePacket的hello_packet_ 消息:SendDispathByID(hell_packet_, 10);
在這個函數裏面首先會檢查10這個服務單元節點是否存在,如果存在而且已連接,就直接調用其Connection進行發送,如果未進行連接,就會將報文放在一個緩衝隊列中,併發起TCP連接,這個時候是直接返回給上層。連接過程是異步的,如果連接完成,就會發送其緩衝隊列中的報文給對端服務單元。這樣做的目的是簡化上層業務和連接管理之間的耦合,降上層業務的複雜度。3消息隱射
class ICmdTarget
{
public:
ICmdTarget();
virtual ~ICmdTarget();
//定義各種觸發參數,例如:SID,mssage class, connection句柄等等
virtual int32_t on_event(uint32_t msg_id, uint32_t sid, CBasePacket* packet, CConnection* connection);
//處理UDP消息
virtual int32_t on_event(uint32_t msg_id, uint32_t sid, CBasePacket* packet, const Inet_Addr& remote_addr);
protected:
virtual CTargetMessageManager* get_message_map() = 0;
};
typedef void (ICmdTarget::*TARGET_CALL)(void);
typedef map<uint32_t, CMD_MESSAGE_ENTRY> CMD_MESSAGE_MAP;
消息隱射是採用類的成員函數進行隱射的,關於類成員函數指針的使用,請查看點擊打開鏈接,有詳細的介紹,我就不再介紹了。
//設置消息處理器
INIT_MSG_PROCESSOR1(&sample_server_);
//設置要處理的消息羣體
LOAD_MESSAGEMAP_DECL(SAMPLE_MSG);
其中INIT_MSG_PROCESSOR是設置消息處理器,LOAD_MESSAGEMAP_DECL是設置需要隱射的消息分類。4 Daemon Client
5 ICoreFrame
class ICoreFrame
{
public:
...
void init();
void destroy();
void start(bool wan = false);
void stop();
//CORE庫的運行函數
void frame_run();
//DAEMON CLIENT返回分配好的地址,進行網絡綁定,如果是DAEMON
void bind_port(uint16_t port);
//組件設置
void create_udp();
void create_tcp_listener();
void create_daemon_client(IDaemonEvent* daemon_event, IDaemonConfig* config = NULL);
void create_dc_client();
void attach_server_notify(ICoreServerNotify* notify);
//提供給上層的事件
virtual void on_init() = 0;
virtual void on_destroy() = 0;
virtual void on_start() = 0;
virtual void on_stop() = 0;
protected:
CDaemonClient* daemon_client_; //DAEMON CLIENT組件
CCoreTCPListener* listener_; //TCP監聽服務組件
CoreUDPHandler* udp_handler_; //UDP服務組件
CCoreDCClient* dc_client_; //DC數據庫訪問組件
};
一般服務如果基於CORE來編寫,就可以通過實現on_init, on_destory, on_start, on_stop來實現服務功能,具體的可以參考revolver 項目sample_server中的sample_frame.cpp