-
- FFRPC 采取Epoll Edge Trigger模式,这里希罕提一下ET是因为在异步工作模式,ET体式格式才是epoll最简单也是高效的体式格式 网上的很多帖子写LT简单易用,那纯碎是没有懂得ET的精华之地点,若是读者想要从ffrpc中商量一下ET的奇妙,提示读者的是 请把Epoll 算作一个状况机!FFRPC 采取Broker模式,如许的益处是 Scalability!! 在游戏范畴的开辟者必然很熟悉Master/Gateway/Logic Server的概念, 实际上Master 实际上扮演的Broker master的角色,而gateway扮演的是Broker slave的角色,Broker Slave负责转发客户端的 恳求到Logic Service,供给一个转发层固然会增长延迟,然则体系变得可扩大,大大进步了吞吐量,这就是Scalability!! 而Broker master负责经管所有的Master Slave,负责负载均衡。不合的client分派不合的Broker SLave。
- FFRPC 就是基于以上的思路,有如下四个关键的概念:
- 一:broker master 负责负载均衡,同步所有节点的信息,所有的slave broker和rpc service/ rpc cleint都要连接broker master。
- 二:slave broker负责完成service和client间转发消息,若是service、client和broker在同一过程,那么直接在内存间送达消息, 这是v0。2的首要的优化,v0。1时没有此功能,网友很多反响这个题目,看来大伙对优化还是太敏感! 另一个创新之处在于ffmsg_t,封装了消息的序列化和反序列化,我已经厌倦了protobuff,若是你也研究了为每个消息定义cmd 和为cmd写switch(有些人可能已经用上注册回调函数,但还有更好用的)。实际上定义消息布局体时一个消息本身就是独一无二的, 所认为什么我们还要给消息在定义一个cmd呢?比如定义了struct echo_t{int a;}消息,echo_t名称本身就是独一无二的,不然编译 器必然报错了,那么为什么不直接用echo_t这个名称作为cmd呢?在FFRPC中可以应用TYPE_NAME(echo_t)获得消息体名称字符串, 是滴TYPE_NAME是一个很有意思的实现,c++中并没哟关键字可以获取一个类的名称,然则所有的编译器都实际上已经供给了这个功能! 详情请看源码。有读者可能会纠结应用消息体布局的名称做cmd固然省事,然则浪费了流量!32位的cmd老是比字符串省流量,是的这个 结论固然我很不喜好(我老是懒的优化,除非...被逼的),然则他是对的!ffrpc中很好的解决了这个题目,当每个节点初始化时都要 注册到broker master,这时所有的消息都邑在master平分派一个独一的msg id,如许就可以用整数1代表echo_t布局了,因为每个节点 都知道echo_t到1的映射,所以法度员再也不消手动定义cmd了,broker独一初始化时动态定义。
- 三:ffrpc service,供给接口的模块,也就就是办事端,经由过程ffrpc类注册的接口基于异步模式,推荐的模式是每个消息都返回 一个成果消息
- 四:ffrpc client是调用的ffrpc service的模块,基于异步模式,记住办事名成和消息名称独一的断定一个接口,这个c++的类和类接口 概念是一致的,并且调用长途接口时可以指定回调函数,并且回调函数还支撑lambda参数绑定!
- 想快速见证ffrpc库的魅力可以小看如下的示例,只要你有linux体系,可以1分钟内测试这个示例,ffrpc没有其他依附,提示你的是 FFRPC的日记组件是彩色的哦!
- ffrpc中broker、client、service可以启动在不合的过程,若是在同一过程,那么直接内存间送达消息
- ffrpc 每个实例零丁启动一个线程和任务队列,包管service和client的操纵都是有序、线程安然的。
- 若是你研究过protobuff、thrift、zeromq、ice等等类库/框架, 更要试用一下ffrpc。
- github 地址 https://github.com/fanchy/FFRPC
ffrpc-c++过程间(办事器端、客户端)通信框架
添加时间:2013-6-7 点击量:FFRPC
github 地址 https://github.com/fanchy/FFRPC
FFRPC 已经陆陆续续开辟了1年,6月6日此日终于完成了我斗劲合意的版本,暂称之为 V0.2,FFRPC实现了一个C++版本 的异步过程间通信库。我本身是做游戏办事器法度的,在办事器法度范畴,体系是分布式的,各个节点须要异步的进行通信, 我的初志是开辟一个易用、易测试的过程间socket通信组件。实际上FFRPC 已经是一个框架。
FFRPC 首要特点
示例代码
#include <stdio.h>
#include base/daemon_tool.h
#include base/arg_helper.h
#include base/strtool.h
#include base/smart_ptr.h
#include rpc/ffrpc.h
#include rpc/ffbroker.h
#include base/log.h
using namespace ff;
//! 定义echo 接口的消息, in_t代表输入消息,out_t代表的成果消息
//! 提示大师的是,这里没有为echo_t定义神马cmd,也没有制订其名称,ffmsg_t会主动可以或许获取echo_t的名称
struct echo_t
{
struct in_t: public ffmsg_t<in_t>
{
void encode()
{
encoder() << data;
}
void decode()
{
decoder() >> data;
}
string data;
};
struct out_t: public ffmsg_t<out_t>
{
void encode()
{
encoder() << data;
}
void decode()
{
decoder() >> data;
}
string data;
};
};
struct foo_t
{
//! echo接口,返回恳求的发送的消息ffreq_t可以供给两个模板参数,第一个默示输入的消息(恳求者发送的)
//! 第二个模板参数默示该接口要返回的成果消息类型
void echo(ffreq_t<echo_t::in_t, echo_t::out_t>& req_)
{
echo_t::out_t out;
out.data = req_.arg.data;
LOGDEBUG((XX, foo_t::echo: %s, req_.arg.data.c_str()));
req_.response(out);
}
//! 长途调用接口,可以指定回调函数(也可以留空),同样应用ffreq_t指定输入消息类型,并且可以应用lambda绑定参数
void echo_callback(ffreq_t<echo_t::out_t>& req_, int index)
{
LOGDEBUG((XX, %s %s %d, __FUNCTION__, req_.arg.data.c_str(), index));
}
};
int main(int argc, char argv[])
{
//! 秀丽的日记组件,shell输出是彩色滴!!
LOG.start(-log_path ./log -log_filename log -log_class XX,BROKER,FFRPC -log_print_screen true -log_print_file true -log_level 6);
//! 启动broker,负责收集相干的操纵,如消息转发,节点注册,重连等
ffbroker_t ffbroker;
ffbroker.open(app -l tcp://127.0.0.1:10241);
//! broker客户端,可以注册到broker,并注册办事以及接口,也可以长途调用其他节点的接口
ffrpc_t ffrpc_service(echo);
foo_t foo;
ffrpc_service.reg(&foo_t::echo, &foo);
ffrpc_service.open(app -broker tcp://127.0.0.1:10241);
ffrpc_t ffrpc_client;
ffrpc_client.open(app -broker tcp://127.0.0.1:10241);
echo_t::in_t in;
in.data = helloworld;
//! 你没有看见get_type_name定义,然则他断定存在
printf(测试获取类名:%s\n, in.get_type_name());//输出为:测试获取类名:echo_t::in_t
for (int i = 0; i < 100; ++i)
{
//! 如你所想,echo接口被调用,然后echo_callback被调用,每一秒反复该过程
ffrpc_client.call(echo, in, ffrpc_ops_t::gen_callback(&foo_t::echo_callback, &foo, i));
sleep(1);
}
sleep(300);
ffbroker.close();
return 0;
}
总结