The examples are a great place to start learning about the event service. Feel free to use them as a starting point for your own clients. The same examples are available as C++, Python and Java. However, this section provides a few more general instructions.
Here's a list of all the ways clients can locate the omniEvents server's EventChannelFactory object:
The -v
option prints the
EventChannelFactory's IOR. You can then use a
straightforward string_to_object()
method call
to turn this into an object reference.
corbaloc::host:port/omniEvents
The EventChannelFactory is registered in the omniORB INSPOA
as omniEvents
which means that you can use the
human readable “corbaloc” string above instead of the
IOR. Replace host
with
omniEvents' hostname and port
with the
TCP port: 11169 (or whatever you chose with the
-p
option).
resolve_initial_references("EventService")
If omniORB.cfg
is properly configured,
you can use resolve_initial_references()
to
find the event service, just as is usually done for the Naming
Service. Just add a line like this:
InitRef = EventService=corbaloc::host:port/omniEvents
omniEvents always registers the EventChannelFactory as a
top-level entry in the naming service. Use the -N
option to control the context, id & kind.
(EventChannelFactory
by default).
The “events” pushed and pulled around by the Event
Service are simply CORBA any
values. The
any
type can hold any CORBA type.
The examples simply send a long
value, but a more
realistic problem would employ a user-defined struct as the
event.
For user-defined types you first need to define the type in
IDL, then compile the IDL. For
omniORB with C++ you would use omniidl -bcxx -Wba.
The -Wba
generates the operators you will need to use
your type with CORBA::Any
.
Here's a small example:
module MyMessages { struct NVPair { NameType name; ValueType value; }; };
Assuming you compile this IDL correctly, you
will have insertion & extraction methods:
operator>>=()
and
operator<<=()
. Here are examples of how to use
them:
CORBA::Any data; // Insert by value MyMessages::NVPair inputNvPair = ... data <<= inputNvPair; // takes a deep copy. // Insert by pointer MyMessages::NVPair* inputNvPairPtr = ... data <<= inputNvPairPtr; // does NOT copy - assumes ownership //XX delete inputNvPairPtr; <== NO!! . . . // Extract const MyMessages::NVPair* outputNvPairPtr = NULL; if(data >>= outputNvPairPtr) { // Use outputNvPairPtr BUT DON'T DELETE IT!! } else { cerr<<"Wrong type!!"<<endl; }
Notice the memory ownership issues. It's best to double check each
time you use <<=
or
>>=
until you're confident you've got it
right.
All Supplier and Consumer objects have a
disconnect_*()
method. This means that each
connection has two disconnect methods, one at each end. Which method
should you call to terminate the connection?
The best approach is to call the Proxy's
disconnect_*()
, rather than your own. (Either will
work, but instructing the Proxy to disconnect is more efficient.)
The rule for implementing your own servant's
disconnect_*()
method is quite simple. Each
disconnect_*()
method should call the other
disconnect_*()
method. It is the responsibility of
the Event Service end (the Proxy) to ensure that an infinite loop
doesn't occur. So clients don't have to worry - they should always just
call the Proxy's disconnect_*()
when their own
disconnect_*()
is called.
There is of course NO GUARANTEE that a
disconnect_*()
method will only be called once. You
should never assume that your servants' methods will not be called until
the object has actually been deactivated in the POA.
It is possible to connect to ProxyPushConsumer & ProxyPullSupplier objects without providing an address for callbacks. When you do that, the proxies cannot call your disconnect method. If you choose to connect to these proxies without providing an address for callbacks, then you must clean up your own objects without help from the Event Service.
These semantics only apply to Event Service v1.1 implementations such as omniEvents v2.6. Earlier specifications were vague about disconnection semantics, so you must be VERY careful if you want to interoperate with an older Event Service implementation (such as omniEvents v2.4 and earlier).