RCF provides support for several third pary serialization frameworks.
Boost.Serialization is a library conceptually similar to RCF's internal serialization framework, providing generic serialization for C++ classes. For reference material and FAQ's on Boost.Serialization itself, please refer to Boost documentation and the Boost mailing lists.
To utilize Boost.Serialization within RCF, you will need to define RCF_USE_BOOST_SERIALIZATION
when building
RCF, and then provide Boost.Serialization serialize()
functions for all your datatypes.
RCF supports two archive types from Boost.Serialization - binary archives
and text archives. To specify which one you want to use, call ClientStub::setSerializationProtocol()
:
RcfClient<I_X> client( RCF::TcpEndpoint(50001) ); // To use Boost.Serialization with binary archives. client.getClientStub().setSerializationProtocol(RCF::Sp_BsBinary); // To use Boost.Serialization with text archives. client.getClientStub().setSerializationProtocol(RCF::Sp_BsText);
If RCF has also been built with RCF_USE_SF_SERIALIZATION
defined, you can also specify SF serialization:
// To use SF serialization. client.getClientStub().setSerializationProtocol(RCF::Sp_SfBinary);
Given the choice between using SF and using Boost.Serialization, which should you use? The answer of course depends largely on the needs of your own application. However, within the context of RCF, we feel SF is a better choice for a number of reasons:
SF::registerType()
and SF::registerBaseAndDerived()
.
Protocol Buffers is an open source project released by Google, which uses a specialized language to define serialization schemas, from which actual serialization code is generated. The official Protocol Buffers compiler can generate code in three languages (C++, Java and Python), and various third party projects are available to provide support for other languages.
RCF provides native marshaling support for classes generated by the Protocol
Buffers compiler. To enable this support, define RCF_USE_PROTOBUF
when building RCF. With RCF_USE_PROTOBUF
defined, classes produced by the Protocol Buffers compiler, can be used
directly in RCF interface declarations, and will be serialized and deserialized
using the Protocol Buffer runtime.
For more information on building RCF with Protocol Buffer support, see Appendix - Building.
As an example, consider this .proto file.
// Person.proto message Person { required int32 id = 1; required string name = 2; optional string email = 3; }
Running the Protocol Buffer compiler (in C++ mode) over Person.proto
results in the two files Person.pb.h
and Person.pb.cc
, containing the implementation of
the C++ class Person
.
// Person.pb.h class Person : public ::google::protobuf::Message { // ... }
To use the class Person
in an RCF interface, simply include Person.pb.h
. RCF will detect that the Person
class is a Protocol Buffer class,
and will use Protocol Buffer functions to serialize and deserialize Person
instances.
#include <RCF/../../test/protobuf/messages/cpp/Person.pb.h> RCF_BEGIN(I_X, "I_X") RCF_METHOD_R1(Person, echo, const Person &) RCF_END(I_X)
Protocol Buffer classes can be intermingled with native C++ classes, in RCF interfaces:
RCF_BEGIN(I_X, "I_X") RCF_METHOD_R1(Person, echo, const Person &) RCF_METHOD_V4(void , func, int, const std::vector<std::string> &, Person &, RCF::ByteBuffer) RCF_END(I_X)
The serialization and deserialization code generated by Protocol Buffers is highly optimized. However, to make the most of this performance, you may want to cache and reuse Protocol Buffer objects from call to call, rather than creating new ones. Protocol Buffer objects will hold on to any memory they allocate, and will reuse the memory in subsequent serialization and deserialization operations.
RCF provides server-side
object caching, for this purpose. For example, to enable server-side
caching of the Person
class:
RCF::ObjectPool & cache = RCF::getObjectPool(); // Enable server-side caching for Person. // * Don't cache more than 10 Person objects. // * Call Person::Clear() before putting a Person object into the cache. cache.enableCaching<Person>(10, boost::bind(&Person::Clear, _1));