1. RCF: 纯c++的RPC, 不引入IDL, 大量用到boost,比较强大.
2. casocklib: protobuf + asio 较完善实现
3. eventrpc: protobuf + libevent 较完善实现
4. evproto: protobuf + libevent 简单实现
5. febird:同样无IDL的c++ RPC,自己实现了串行化和网络IO.
6. libHttp, xmlrpc 都是xml封装的RPC
以下是某专家的详解:
http://blog.csdn.net/lanphaday/archive/2011/04/12/6318432.aspx
(原文还包括java,python)
先看它的简介:An asynchronous communication library for C++,而它基本包格式见:http://code.google.com/p/casocklib/source/browse/trunk/src/casock/rpc/protobuf/api/rpc.proto ,如下:
代码很短,采用了相当轻量级的设计。首先旗帜鲜明地声明了响应包的种类:成功以及失败,对于失败,并没有细分。RpcRequest.id 使用 32 位无符号整型,跟 protobuf-rpc 一样,不过这里的 operation 却跟后者的 method 不一样,operation 是货真价实的 MethodDescriptor.name,从代码(http://code.google.com/p/casocklib/source/browse/trunk/src/casock/rpc/protobuf/client/RPCRequestBuilder.cc#50 )可以证实。因为每一个 RpcRequest.operation 都不带 service name,所以使用 Casocklib 是无法将多个 service host 到同一个端口的。
RpcResponse 因为带了一个 ResponseType,所以可以知道 method 到底有没有执行成功,同理 response 就设计成 optional 了,因为执行错误就不需要返回 response 了呀
嘎~再来一枚 C++ 系的 RPC,它的简介是 RPC implementation for C# and C++ using Protocol Buffers,比之前的几个 rpc 实现都要复杂。基本格式见:http://code.google.com/p/protobuf-remote/source/browse/Cpp/Source/ProtoBufRemote/RpcMessage.proto ,全文如下
只有一个大定义:message RpcMessage,它即是 request 又是 response,这一点跟之前的 protobuf-rpc 的 Rpc 相同;但不同的是它把 id 从 call/result(对应常用的 request/response)中抽取出来作为 RpcMessage 的共有属性,不过我没看到它的做法的时候,还真没想过要抽取出来,看来我重构能力有待加强。
从 Call 来看,采用了 service 和 method 分开两个字段的设计,所以 multi-service 是没有问题的。repeated Parameter parameters 让我有点困惑,因为之前所看的设计,应该都是使用 bytes 存储序列化好的 message 对象,那么这个 parameters 是否有独到之处,有的话又是什么呢?抱着这样的疑惑,我翻开了它的代码(额,测试代码,因为简单好懂,见:http://code.google.com/p/protobuf-remote/source/browse/Cpp/Source/ProtoBufRemoteTest/RpcClientTest.cpp#76 ):
可以看到声明了一个 RpcMessage 变量,然后用它实例化了一个 MutableParameterList(这个 MutablePararmeterList 可以看作是 Call.parameters 的适配器),然后往里加入了一个整型参数 42,然后再调用 Call 方法把请求发送到服务器端。至此我们可以明白 parameters 的作用是让我们声明 rpc 的时候,不再需要详细定义相应的参数和返回值类型了,统一写成:
即可,唯一需要变化的是用真正的方法名替换掉 XXXX。而 repeated Parameter parameters 中 repeated 的作用是为了传入复合参数,比如按常规传入 protobuf 官方示例中的 message Person 参数的话,可能在这里是这样的:
不过如果有定义 message Person 的话,也可以这样:
可见各种方案都有利弊,获得了 rpc 声明的简洁,就需要牺牲代码的简洁为代价。虽然说作者的思路的确是如同天马行空般开阔,但如果是我的话,我不会采用这种方案,换作你呢,又会如何?
Call.expects_result 字段是告诉服务器端要不要把结果(包括是否出错)返回给客户端,很好理解。不过 Result.call_result 是 optional,而不是 repeated,让我觉得怪怪地,难道只准多个参数,不许多个返回值?
server1 出自国人之手,是一个利用了 Boost 的 a c++ network server/client framework,它的作者 xiliu tang 是我的前同事。server1 的代码还是非常简明的,先来看一下基础格式:http://code.google.com/p/server1/source/browse/trunk/server/meta.proto ,全文如下:
很简单,只有一个 message MetaData?对的。感觉上跟 protobuf-rpc 差不多,两个不同:一是 MetaData 带了一个 Type,用来标明它是请求还是响应;还有一个是 MetaData 使用了无符号 64 位整型作为 ID。使用 type 字段我个人感觉比 repeated/optional 的方式比起来有点没有充分利用到 protobuf 特性的感觉,不过相当地清晰明了。还有就是 response_identify 我专门在 GTalk 上问过作者,他说记不起为什么要加这个字段了……囧。我的看法是这个字段是不必要的。嗯,这个设计真的很简洁,不过,我不喜欢 Meta 这个命名。