EII Message Bus C Reference
|
Protocols are at the bottom most layer of the EII Message Bus stack. They provide the implementation for the messaging primitives supported by the EII Message Bus. The main tasks expected of a protocol are as follows:
msg_envelope_t
structureAll protocols must have a unique protocol name which the EII Message Bus can use to load the protocol based on the type
configuration value it is provided. For example, the ZeroMQ TCP protocol uses the identifier zmq_tcp
. Using this type name, the EII Message Bus knows how to load the protocol in the msgbus_initialize()
method.
Currently, the addition and loading of new protocols must be added directly to the source code for the EII Message Bus. In the future, the message bus will include a feature for dynamically loading protocol plugins. All protocols are expected to have an initialize method which follows the prototype: protocol_t* proto_<type>_initialize(const char* type, config_t* config)
. This method is expected to initialize the underlying messaging library using the given config
parameter and then return a pointer to a protocol_t
structure which has pointers for all of the various messaging functions. This method must then be added manually to the msgbus_initialize()
function in src/msgbus.c
.
The protocol_t
structure is defined below.
It is expected that this structure is fully populated by a protocol's initialization method. The proto_ctx
value should be a pointer to an internal structure representing the state of the protocol which the various functions can use to perform the required tasks. Additionally, the config
value should be set to the config
variable passed to the initialization function. It is important to note that the returned protocol_t
structure is not responsible for freeing the memory assiciated with the config
variable. This is managed by the message bus context object.
For each of the functions in the structure the first ctx
parameter will always be the value of the proto_ctx
variable.
For more information on the purpose of each of the function pointers in the protocol_t
structure see the protocol_t
Function Definition.
The rest of this section will cover the initial setup of a project to add a new protocol to the EII Message Bus, including the ideal code structure for the C source code file.
For the purposes of this tutorial, the name of the proctol to be added will be named example
. To start, create a new header file in the include/eii/msgbus
directory and a new C file in the src
directory.
NOTE: The names of the files above should be the name of your protocol.
Once these files are created, add the following to the example.h
file.
The code above defines the initialization method for initializing the example
protocol.
Next, modify the src/msgbus.c
file to call the new proto_example_intiialize()
method if the type configuration parameter is set to example
.
First, include the example.h
header file on line 36 in the src/msgbus.c
file.
Then, add the following code at after line 210.
Next, extend the if...else...
block from lines 212 to 219 to add an else if
clause for if the the protocol type is example
. The entire code block should look as follows in the end.
Once these steps are completed, switch to the src/example.c
file to add the protocol implementation. The recommended structure of the code in this file is shown below.
The code below first defines a set of common header file includes, including the example.h
header file. Following this are the function prototypes for all of the needed function pointers in the protocol_t
structure.
After these definitions lies the implementation for the proto_example_initialize()
function. The TODO
comments represent areas where code must be added depending on the protocol being added to the EII Message Bus. The code then intializes the protocol_t
struct and assigns all of the proper pointers.
After the implementation for the proto_example_initialize()
function are all of the function imlementations for the prototypes defined at the top of the file.
Once this file is saved as src/example.c
, compile the EII Message Bus. The examples should all work, however, they should immediately return or potentially raise an error, since this is an empty protocol implementation and none of the return objects are being initialized.
protocol_t
Function DefinitionThe following describes the purpose of each of the function pointers above.
destroy()
Responsible for destroying the proto_ctx
variable and freeing any memory used by the context.
publisher_new()
Initializes a new publisher context for the given topic
.
publisher_publish()
Publishes the given message value using the publisher context.
publisher_destroy()
Destroys a context for a publisher freeing any sockets, memory, etc. used by the publisher.
subscriber_new()
Subscribe to the given topic and output a recv_ctx_t
to use with the recv_*
methods to receive the publications for the topic.
service_new()
Create a new recv_ctx_t
structure which can be used to received requests from clients and send responses to received requests using the response()
method.
service_get()
Create a new recv_ctx_t
structure which can be used to issue requests to and received responses from the specified service.
recv_ctx_destroy()
Destroy a recv_ctx_t
structure.
request()
Issue a request to the service using the given recv_ctx_t
.
response()
Send a response to a requesting client using the given recv_ctx_t
structure.
recv_wait()
Blocking function for receiving a message from a recv_ctx_t
context structure.
recv_timedwait()
Function for receiving messages from a recv_ctx_t
context structure which times out after the given timeout. The timeout shall always be milliseconds.
recv_nowait()
Receive a message from a recv_ctx_t
context structure if a message is available, otherwise return immediately.