ORBit2 Tutorial V1.1 | ||
---|---|---|
<<< Previous | Next >>> |
The programming language C is widely used for implementations of servers all over the world. Most often C is used because of performance and because of linking to third party libraries. Just imagine a huge application project shared by various companies each one implementing a specific module of the overall system. As all modules shall be linked to a single binary in the end, it is necessary to agree on APIs but also on binary compatibility. If choosing programming language C most compilers are binary compatible, in contrast to C++ compilers. The following chapter demonstrates how to add an ORBit2 remote method call interface to an existing library/module, using programming language C.
For some reason someone did implement a mailbox system for management of incoming and outgoing mails for his hometown postoffice and now the postoffice wants to offer its services in internet for distributed client/server interaction. The management did invest a big amount of money and time allready for the mailbox system and they would like to minimize risc and investment for the upcoming internet application. They have to choose between SOAP and CORBA. After some investigation they find out that SOAP would interfere with pre-existing Web server sharing same resources and as SOAP is based on stringified encoding it would not suffice performance criteria. In contrast, CORBA is based on binary encoding and up to 20 times faster, it is a widespread standard, widely used since years supporting strong security mechanisms. For that reason they make their choice for CORBA, adding a remote interfaces as thin wrapper for existing code. As we will see
Please have a look for the code here: postoffice C code
The interface of the mailbox system is given as C header file and looks like:
Table 5. counter.h
|
Const Annotation | |
---|---|
If function arguments are declared as 'const' the function will copy the data if needed; the function will not store any reference to the user's data and therefore you may free the data any time after the method call. |
Now the professionals design an extendible remote interface, that wraps the existing desktop system and introduces concepts of object oriented programming and exception handling. Finally they come to an IDL that equals the IDL we allready used for our python implementation of server/client, but, well, good design often comes to similar results **grin**
Table 6. postoffice.idl
|
Implementing the remote interface is quite simple. As first step you need to generate intermediate C code from IDL file. This code will do marshaling and demarshaling of data for you every time data is being exchanged between client and server.
bash$ orbit-idl-2 postoffice.idl orbit-idl-2 2.4.1 compiling small mode, show preprocessor errors, passes: stubs skels common headers skel_impl imodule |
This command has created a number of files, their role for client and server is shown in table:
Table 7. orbit-idl-2 generated files
client | server | |
---|---|---|
exclusive files | postoffice-stubs.c | postoffice-skels.c |
shared files | postoffice.h & postoffice-common.c |
The implementation of our server shall be based on those files generated previously, and two additional files 'postoffice-server.c' and 'postoffice-skelimpl.c'. Whereas the first file contains the 'main' function and is used to set up the servant, the latter is a template file generated from 'postoffice.idl' and must be extended by user for specific features of servant. The template file is going to be generated with command:
bash$ orbit-idl-2 --skeleton-impl postoffice.idl orbit-idl-2 2.4.1 compiling small mode, show preprocessor errors, passes: stubs skels common headers imodule |
The user shall insert its code into template file 'postoffice-skelimpl.c' which represents the adaptor to 'postoffice-skel.c'. For each interface and method declared in file 'postoffice.idl' a body fragment exists where the user shall insert its code. All interface methods are bundled in single virtual method table (vtable) that is handed over to to CORBA object manager. For each incoming request the object manager consults this vtable to find the corresponding method implementation.
Table 8. postoffice.h (vtable)
|
The function POA_PostOffice_Counter__init represents the constructor whereas POA_PostOffice_Counter__fini represents the desctructor of managed PostOffice objects. These functions mark lifetime of PostOffice objects and must be invoked at beginning and end. These function are independend of user defined service interfaces and are registered seperately. The user may extend the destructor using a wrapper but must register its function for CORBA object manager in the following structure. This fragment of of postoffice-skelimpl.c shows all prototypes of interface methods and of user defiend desctructor and its registration for CORBA framework.
Table 9. orbit.h (object vtable)
|
Now that we have these structures we can deal about creating instances. Well, but how shall its class structure look like? What attributes shall an object contain storing state? Here the generated file postoffice-skelimpl.c gives you a hand caontaining a predefined structure that fullfills all constrains of CORBA framework and may be extended further by user. Additional attributes may be declared at end of structure only.
Table 10. postoffice-skelimpl.c (object structure)
|
The following function demonstrates how to extend the predefined function in postoffice-skelimpl.c with user code. In case of failures the user code must contain apropiat exception handling. Here the object is being destroyed and function returns the NIL object.
Table 11. postoffice-skelimpl.c (object creation)
|
In similar fashion user must extend the predefined destructor template. After the object has been deactivated and no further remote request can occure the object manager calls the user defined destructor, ie. impl_PostOffice_Counter__destroy. Here the user must free those resources the object did collect during lifetime. Finally the memory allocted by structure of servant itsself will be released by object manager. .
Table 12. postoffice-skelimpl.c (object destruction)
|
Let's have a look at those three functions that are part of the interface. As you can see each CORBA function is a wrapper for some function of the mailbox system. In fact only little code has to be written for the remote invocation interface. Please note that the wrapper functions transform incoming middleware-data to data-structures used by the old mailbox system. The reason is that the ORBit system (CORBA) and the mailbox system are using different kinds of memory management. Data allocated by ORBit system should never be freed by code of mailbox system code and vice versa.
Table 13. postoffice-skelimpl.c (object method definitions)
|
Three "helper" functions are going to be used for copying and freeing of data:
Table 14. postoffice-skelimpl.c
|
All that is missing now is setting up the application, including signal handling with specifi 'handler' function:
Table 15. postoffice-server.c
|
If you want to test this server, you can use the version implemented with Python, or you read further on. The next lines will explain how to write the client using programming language C.
Lets write a first PostOffice-client using programming language C. This client will do synchronous method calls to server. Other examples shall demonstrate how to realize asynchronous method invocation with CORBA, but this is another story.
As you can see here is is simple to write exception safe CORBA clients.
Table 16. postoffice-client.c
|
Now you can compile the the code and invoke server and client:
bash$ ./postoffice-server > objref.ior |
bash$ ./postoffice-client < objref.ior |
<<< Previous | Home | Next >>> |
Quick Start with Python | Asking for bugs |