ProtocolBufferConverter » History » Version 17

« Previous - Version 17/19 (diff) - Next » - Current version
J. Moringen, 08/06/2011 12:45 AM
added implementation links


ProtocolBufferConverter

Warning: this tutorial explains how to use RSB's converter mechanism for domain data which is represented in Google protocol buffer messages. However, Google's protocol buffer tutorial advises against using protocol buffer messages directly as domain classes (see "Protocol Buffers and O-O Design" in the protocol buffer tutorial).

Introduction

Google protocol buffers are an approach for IDL-driven generation of data-holder classes and associated serialization and deserialization code. In RSB, arbitrary protocol buffer messages can be processed using the converter mechanism. Depending on the programming language, the particular protocol buffer messages, that will be used, may have to be registered in the converter system in some way. However, after the registration, serialization and deserialization works transparently without further implementation or configuration work.

Advantages of this approach over manual converter writing (as described here) include:

  • IDL-defined message format (as opposed to an informal "definition" through a particular implementation)
  • Proper handling of machine Endianess
  • Proper handling of machine word sizes
  • Some degree of data validation
  • Introspection support
  • Generated data-holder classes and (de)serializers
    • Available in multiple programming languages without additional effort
    • Inter-language consistency of data-holder classes and serialized representations

This page describes how to use the ProtocolBufferConverter class with user-defined protocol buffer messages. The running example of a fictional SimpleImage data-type (introduced here) is reused.

Message Definition

A SimpleImage consists of

  • a width (a non-negative integer)
  • a height (a non-negative integer)
  • image data (an array of bytes)

This structure is reflected in the protocol buffer message definition:

source:trunk/cpp/core/examples/protobuf_converter/SimpleImage.proto

Code

C++

As explained above, no code has to be written for the data-holder class or its (de)serialization. However, it is necessary to register a template instantiation of the ProtocolBufferConverter class in the converter registry. The sender and receiver program demonstrate how to do this and additionally send and receive SimpleImage messages respectively.

source:trunk/cpp/core/examples/protobuf_converter/sender.cpp
source:trunk/cpp/core/examples/protobuf_converter/receiver.cpp

Java

Java support for Protocol Buffer encoding of user-level datatypes is available since RSB version 0.4.

source:trunk/java/core/examples/tutorial/protobuf/InformerExample.java
source:trunk/java/core/examples/tutorial/protobuf/ListenerExample.java

Please note that converter instances of the same type can only be registered once in the default converter repository. If a converter is already registered for the same type, you will receive an IllegalArgumentException. Hence, the current best practice is to register all types used in an application upon startup. In future RSB versions, this will be handled via the configuration subsystem.

To invoke the protocol buffer compiler and generate the necessary data holders and (de)-serialization classes, you may adapt the following ant snippet (taken from RSBJava's source:trunk/java/core/build.xml) to your project by adding it to your ant build file (usually build.xml):

<!-- required parameters -->
<property name="pbuf.protoc" location="/usr/bin/protoc" />

<!-- protocol buffer generation -->
<target name="protocol">
    <apply executable="${pbuf.protoc}">
        <arg value="--java_out=examples" />
        <arg value="--proto_path=${basedir}/examples/tutorial/protocol" />
        <fileset dir="examples/tutorial/protocol" includes="*.proto" />
    </apply>
</target>

This target takes the proto files you provide from pbuf.protopath and generates the corresponding Protocol Buffer Java source classes to ${basedir}/examples/tutorial/protocol. In turn, you need to include these classes as regular Java source classes in subsequent build steps of your project. Additionally, you may want to add a dependency on the protocol target in your compile target(s):

<target name="compile" depends="init, protocol" description="compile the source ">
<!-- ... -->

Python

source:trunk/python/core/examples/protobuf/informer.py
source:trunk/python/core/examples/protobuf/listener.py

Common Lisp

source:trunk/cl/cl-rsb/examples/protocol-buffers/sender.lisp
source:trunk/cl/cl-rsb/examples/protocol-buffers/receiver.lisp

Implementations

Language File(s)
C++ source:trunk/cpp/core/src/rsb/converter/ProtocolBufferConverter.h,source:trunk/cpp/core/src/rsb/converter/ProtocolBufferConverter.cpp
Java source:trunk/java/core/src/rsb/converter/ProtocolBufferConverter.java
Python source:trunk/python/core/rsb/transport/converter.py
Common Lisp source:trunk/cl/cl-rsb/src/converter/protocol-buffers.lisp