All operations are perfomed in the Tonido framework by sending and passing messsages (specifically objects of the type Message). To become an endpoint of communication in the Tonido framework, one needs to derive from the Service class and become a service. The appropriate service is invoked when a message meant for that service is sent.
Messages are routed between services within Tonido using the message dispatcher. ( MessageDispatcher). There is only a single instance of the Message Dispatcher in every Tonido process. To provide a simple analogy, a message dispatcher is like a post man delivering letters. To send a message, similarly like a letter, the message needs to have recipient details filled out as well optionally the sender details filled out. Then the message is handed off to the dispatcher, who will first see to whom the message is addressd and then it will hand him the message. Note that if no addressee is found, the message is dumped.
The message dispatcher can only talk to objects which have specific endpoints defined by the Service abstract class. So any object wishing to receive messages from the Message Dispatcher has to derive from the Service class. Note that to send messages via the dispatcher there are no type requirements on the sender.
See this below, where Service1 is trying to send a message to Service2
The advantages of such an architecture are the following:
The disadvantages of this approach include:
A service's functions are called in a strict sequence:
Service init
|
|
Service startup
|
|
Service onMessage (Many Times)
|
|
Service shutdown
Here's what a normal service would do during each of these functions:
Service::init(const std::string& a_basePath)
The init function is called before the plugin service is started and allows the plugin service to do any required initialization. Note that the plugin is called with the basePath from where the plugin is being loaded from. The base path is useful if the plugin wants to locate other files that are shipped along with itself.
Service::startup(MessageDispatcher* a_dispatcher)
The startup is called after init and the plugin is responsible to ready itself for receiving messages via the onMessageHandler right after this call.
Every plugin SHOULD do these during it's startup:
Optionally, every plugin can do these other things
Service::shutdown()
The shutdown function is called when the plugin is being shutdown. This could be due to several events,
The plugin SHOULD do the following things in it's shutdown function:
Service::onMessage(const void* a_pSender, Message::SharedPtr& a_pMessage)
This is the main service request handler that every plugin should implement. Any message being routed to this function indicates an incoming message from a service originating locally or remotely that wants to send a message to this specific name.
Here are the guidelines for implementing the onMessage function
The following Services are currently available in the Tonido Framework: