Event Handler Concepts
Event Handler Concepts
Event handlers objects allow client application and object implementations to define methods that the ORB will invoke to handle events such as the success or failure of a bind request or the failure of an object implementation. Two different event handler classes are provided because the types of events that can be handled are different for clients and object implementations. However, the procedure for using an event handler is similar for clients and object implementations.
Client-side Events
Bind succeeded
Bind Failed
Server aborted
Rebind succeeded
Rebind failed
Implementation-side Events
Bind request received
Unbind request received
Client aborted
Pre-method
Post-method
The following example shows a portion of the pmcext.h include file that contains the class definition for the
ClientEventHandler
class.
class PMC_EXT{
struct ConnectionInfo {
CORBA::String_var hostname;
CORBA::UShort port;
CORBA::Long fd;
...
};
class ClientEventHandler
{
public:
virtual void bind_succeeded(CORBA::Object_ptr,
const ConnectionInfo&);
virtual void bind_failed(CORBA::Object_ptr);
virtual void server_aborted(CORBA::Object_ptr);
virtual void rebind_succeeded(CORBA::Object_ptr,
const ConnectionInfo&);
virtual void rebind_failed(CORBA::Object_ptr);
...
};
...
};
The
bind_succeeded
method is called by the ORB when the client's request to bind to the ORB object has completed successfully. A pointer to the object that has been bound is provided as a parameter as well as the connection information.The
bind_failed
method is called if the client's bind request fails. A pointer to the object to which the event is related is provided as a parameter.The
server_aborted
method is called if the connection to the object implementation is lost. A pointer to the object to which the event is related is provided as a parameter.The
rebind_succeeded
method is called when an attempt to re-connect to an object implementation succeeds. A pointer to the object that has been re-bound is provided as a parameter as well as the new connection information.The
rebind_failed
method is called when an attempt to re-connect to an object implementation fails. A pointer to the object to which the event is related is provided as a parameter.
The following example shows how you would define an event handler for the library client, introduced in Chapter 2. Only three of the possible five methods offered by ClientEventHandler have been overridden.
class LibraryClientHandler : public PMC_EXT::ClientEventHandlerThe following example shows simple implementations for these methods.{
...
public:
void bind_succeeded(CORBA::Object_ptr, const ConnectionInfo&);
void bind_failed(CORBA::Object_ptr);
void server_aborted(CORBA::Object_ptr);
};
void LibraryClientHandler::bind_succeeded(CORBA::Object_ptr obj,const ConnectionInfo&)
{
cout << "Event Handler bind_succeeded for: "
<< obj->_interface_name() << endl;
}
void LibraryClientHandler::bind_failed(CORBA::Object_ptr obj)
{
cout << "Event Handler bind_failed for: "
<< obj->_interface_name() << endl;
}
void LibraryClientHandler::server_aborted(CORBA::Object_ptr obj)
{
cout << "Event Handler server_aborted for: "
<< obj->_interface_name() << endl;
}
HandlerRegistry::instance
to obtain a pointer to the registry and then invoke the methods for registering and un-registering various types of event handlers.
class HandlerRegistry{...
public:
...
static HandlerRegistry_ptr instance();
void reg_obj_client_handler(CORBA::Object_ptr obj,
ClientEventHandler_ptr handler);
void reg_glob_client_handler(ClientEventHandler_ptr handler);
void unreg_obj_client_handler(CORBA::Object_ptr obj);
void unreg_glob_client_handler();
void reg_obj_impl_handler(CORBA::Object_ptr obj,
ImplEventHandler_ptr handler);
void reg_glob_impl_handler(ImplEventHandler_ptr handler);
void unreg_obj_impl_handler(CORBA::Object_ptr obj);
void unreg_glob_impl_handler();
...
};
reg_obj_client_handler
method can be called by your client application to register an event handler for a specific object. The parameters passed to this method are a reference to the object and a pointer to the object's ClientEventHandler
. If the object reference is not valid, an InvalidObject
exception will be raised. If an event handler has already been registered for the specified object, a HandlerExists
exception will be raised. You can use the unreg_obj_client_handler
method to un-register a previously registered event handler.The
reg_glob_client_handler
method can be called by your client application to register an event handler for all object the client uses. The parameter passed to this method is a pointer to the object's ClientEventHandler
. If a global handler has already been registered, a HandlerExists
exception will be raised. You can use the unreg_glob_client_handler
method to un-register a previously registered global event handler.Note: If both an object event handler and a global event handler are registered, the object event handler will take precedence for events that occur which are related to its object. All other events will be handled by the global event handler.
The
unreg_obj_client_handler
method can called by your client application to un-register an event handler for a specific object. A reference to the object whose event handler is to be removed is passed as a parameter. If the object reference is not valid, an InvalidObject
exception will be raised. If no event handler has been registered for the specified object, a NoHandler
exception will be raised.The
unreg_glob_client_handler
method can called by your client application to unregister a global event handler. If no global event handler has been registered, a NoHandler
exception will be raised.
PCM_EXT::HandlerRegistry::instance
method to obtain a pointer to the ORB's event handler registry. The following example shows the registration process for a global event handler and shows how to register a per-object event handler. Both examples assume that the LibraryClientHandler class has been defined and implemented, as shown in the previous examples.The following example shows how to register a global client event handler.
#include <fstream.h>The following example shows how to register a per-object client event handler.#include <lib_client.hh>
main(int argc, char *const *argv)
{
CORBA::Boolean ret;
// Initialize the ORB
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Parse arguments
...
// Declare the library object
library_var *library_object;
// Declare the library event handler
LibraryClientHandler client_handler;
// Obtain a handle to the ORB's registry
PCM_EXT::HandlerRegistery_ptr registry_handle =
PCM_EXT::HandlerRegistry::instance();
try {
// Register the global event handler
registry_handle->reg_glob_client_handler(&client_handler);
}
catch(const PMC_EXT::HandlerExists& excep) {
cout << "A global handler was already registered" << endl;
}
// Bind to the library object and invoke methods
...
try {
// Un-register the global event handler
registry_handle->unreg_glob_client_handler();
}
catch(const PMC_EXT::NoHandler& excep) {
cout << "No global handler was registered" << endl;
}
return(1);
}
#include <fstream.h>#include <lib_client.hh>
main(int argc, char *const *argv)
{
CORBA::Boolean ret;
// Initialize the ORB
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Parse arguments
...
// Declare the library object
library_var *library_object;
// Bind to the library object
...
// Declare the library event handler
LibraryClientHandler client_handler;
// Obtain a handle to the ORB's registry
PCM_EXT::HandlerRegistery_ptr registry_handle =
PCM_EXT::HandlerRegistry:::instance();
try {
// Register the library event handler
registry_handle->reg_obj_client_handler(library_object,
&client_handler);
}
catch(const PMC_EXT::HandlerExists& excep) {
cout << "A handler was already registered" << endl;
}
// Invoke methods on library object
...
try {
// Un-register the library event handler
registry_handle->unreg_obj_client_handler(library_object);
}
catch(const PMC_EXT::NoHandler& excep) {
cout << "No handler was registered" << endl;
}
catch(const PMC_EXT::InvalidObject& excep) {
cout << "Invalid object reference" << endl;
}
return(1);
}
class PCM_EXTIn the preceding example,{
...
class ImplEventHandler
{
public:
virtual void bind(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr);
virtual void unbind(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr);
virtual void client_aborted(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr);
virtual void pre_method(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr,
const char *, CORBA::Object_ptr);
virtual void post_method(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr,
const char *, CORBA::Object_ptr);
};
...
};
CORBA::Principal_ptr
allows clients to send information to the server that can retrieve this data and, as the implementor, you can determine if the server allows the action (like a bind) to be performed.
bind
method will be called every time a client wishes to connect to this object. This method allow your object implementation to do any special processing before the bind request is processed. Once this method returns, the BOA will proceed with the normal binding process. The parameters passed to this method are the connection information, the Principal value associated with the client and a pointer to the ORB object requested. This method may choose to reject the bind, based on the requestor's identity, by raising a CORBA::NO_PERMISSION
exception.The
unbind
method will be called every time a client application calls the CORBA::release method for a previously bound object. The BOA will pass control to this method before the un-bind occurs. The connection information and the object reference are passed to this method.The
client_aborted
method will be called if the connection to a client application is lost. The connection information and the object reference are passed to this method.The
pre_method
method will be called every time a client application invokes a method on the object for which the handler is registered. After this method returns, the BOA will proceed with the method invocation. The connection information, Principal of the client, method name and a pointer to the object are all passed to this method.The
post_method
method will be called after every invocation of a method by a client on the object being traced. After this method returns, the results of the method invocation will be returned to the client. The connection information, Principal
of the client, method name and a pointer to the object are all passed to this method.Note: If the method invoked by the client raises an exception, post_method will not be called.
Library
object by deriving your own class from the ImplEventHandler
class.
class LibraryImplHandler : public PMC_EXT::ImplEventHandlerThe following example shows the implementation for the{
public:
void bind(const ConnectionInfo&, CORBA::Principal_ptr,
CORBA::Object_ptr);
void unbind(const ConnectionInfo&, CORBA::Principal_ptr,
CORBA::Object_ptr);
};
LibraryImplHandler
methods defined. You only need to define and provide method implementations for those events you wish to handle.
void LibraryImplHandler::bind(const ConnectionInfo&,CORBA::Principal_ptr, CORBA::Object_ptr obj)
{
cout << "Bind request arrived for " << obj->_interface_name << endl;
...
};
void LibraryImplHandler::unbind(const ConnectionInfo&,
CORBA::Principal_ptr, CORBA::Object_ptr obj)
{
cout << "Un-Bind request arrived for " << obj->_interface_name << endl; ...
};
reg_obj_impl_handler
method can be called by your object implementation to register an event handler with the BOA for a specific object. The parameters passed to this method are a reference to the object and a pointer to the object's ImplEventHandler
. If the object reference is not valid, an InvalidObject
exception will be raised. If an event handler has already been registered for the specified object, a HandlerExists
exception will be raised. You can use the unreg_obj_impl_handler
method to un-register a previously registered event handler.The
reg_glob_impl_handler
method can be called by your object implementation to register an event handler with the BOA for all objects contained in the implementation. The parameter passed to this method is a pointer to the object's ImplEventHandler
. If a global handler has already been registered for this implementation, a HandlerExists
exception will be raised. You can use the unreg_glob_impl_handler
method to un-register a previously registered global event handler.Note: If both an object event handler and a global event handler are registered, the object event handler will take precedence for events that occur which are related to its object. All other events will be handled by the global event handler.
The
unreg_obj_impl_handler
method can be called by your object implementation to un-register an event handler for a specific object. A reference to the object whose event handler is to be removed is passed as a parameter. If the object reference is not valid, an InvalidObject
exception will be raised. If no event handler has been registered for the specified object, a NoHandler
exception will be raised.The
unreg_glob_impl_handler
method can be called by your object implementation to un-register a global event handler. If no global event handler has been registered, a NoHandler
exception will be raised.
#include <lib_server.hh>The following example shows how to register a per-object event handler. The example assumes that the LibraryImplHandler class has been defined and implemented, as shown in a previous example.int main(int argc, char **argv)
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_ptr boa = orb->BOA_init(argc, argv);
// Instantiate the Library object
Library *library_obj = new Library("Harvard");
// Define the impl_handler and registry instance
LibraryImplHandler impl_handler;
PMC_EXT::HandlerRegistry_ptr registry_handle;
registry_handle = PMC_EXT::HandlerRegistry::instance();
try {
// Register a global event handler
registry_handle->reg_glob_impl_handler(&impl_handler);
}
catch(const PMC_EXT::HandlerExists& excep) {
cout << "Global handler already defined" << endl;
}
// Instantiate Library Class, activate object and implementation
...
try {
registry_handle->unreg_glob_impl_handler();
}
catch(const PMC_EXT::NoHandler& excep) {
cout << "Removal of global event handler failed" << endl;
}
...
}
#include <lib_server.hh>int main(int argc, char **argv)
{
// Initialize ORB and Basic Object Adaptor (BOA)
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
CORBA::BOA_ptr boa = orb->BOA_init(argc, argv);
// Instantiate the Library object
Library *library_obj = new Library("Harvard");
// Define the impl_handler and registry instance
LibraryImplHandler impl_handler;
PMC_EXT::HandlerRegistry_ptr registry_handle;
registry_handle = PMC_EXT::HandlerRegistry::instance();
try {
// Register a global event handler
registry_handle->reg_obj_impl_handler(library_obj, &impl_handler);
}
catch(const PMC_EXT::HandlerExists& excep) {
cout << "Handler already defined for " <<
library_obj->_instance_name << endl;
}
// Instantiate Library Class, activate object and implementation
...
try {
registry_handle->unreg_obj_impl_handler(library_obj);
}
catch(const PMC_EXT::NoHandler& excep) {
cout << "Removal of event handler failed for " <<
library_obj->_instance_name << endl;
}
...
}