Event Handler Concepts
|
Client Event Handlers
|
Implementation Event Handlers
|
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.
Derive an event handler class for your object, defining the event methods you wish to handle.
Client Event Handlers
Client applications can register an event handler with the ORB to handle events for a particular ORB object. The client can also globally register an event handler to handle events for all ORB objects the client uses. The following code listing shows a portion of the pmcext.h
include file that contains the class definition for the ClientEventHandler
class.
The ConnectionInfo
structure and 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 ConnectionInfo Structure
This structure represents all the information needed for a connection. It includes the host name where the object implementation resides, the port number and the file descriptor used for the connection. This structure is modified when the connection to the object implementation is lost and a re-bind operation is attempted.
ClientEventHandler Methods
When an event handler object has been registered for a particular ORB object, the ORB will call the ClientEventHandler
methods when a specific event occurs. If the event handler is registered as a global event handler, the ClientEventHandler
methods will be called for any event related to any object the client uses.
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.
Creating a Client Event Handler
To implement an event handler for your client application, derive an event handler class for the class you wish to monitor. You need to implement only those event handler methods you wish to override. If you do not override an event handler method, no special processing will occur and no performance overhead will be added to the application.
The following code example defines an event handler for the library application.
An example event handler for the library client.
class LibraryClientHandler : public PMC_EXT::ClientEventHandler
Only three of the possible five methods offered by ClientEventHandler have been overridden. The following code listing shows simple implementations for these methods.
Implementation for the
{
...
public:
void bind_succeeded(CORBA::Object_ptr, const ConnectionInfo&);
void bind_failed(CORBA::Object_ptr);
void server_aborted(CORBA::Object_ptr);
};LibraryClientHandler
method.
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;
} The Handler Registry
You can use the static method HandlerRegistry::instance
to obtain a pointer to the registry and then invoke the methods for registering and un-registering various types of event handlers.
The HandlerRegistry
class.
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();
...
}; HandlerRegistry Methods for Clients Applications
The 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 code examples show the registration process for a global event handler and shows how to register a per-object event handler. They both assume that the LibraryClientHandler class has been defined and implemented.
Registering a global client event handler.
#include <fstream.h>Registering a per-object client event handler.
#include <lib_client.hh>
int 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
LibraryClientHandlerclient_handler;
// Obtain a handle to the ORB's registryPCM_EXT::HandlerRegistery_ptr registry_handle = PCM_EXT::HandlerRegistry::instance();
try {
// Register the global event handler
registry_handle->reg_glob_client_handler(&client_handler);
}
catch(constPMC_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(constPMC_EXT::NoHandler& excep
) {
cout << "No global handler was registered" << endl;
}
return(1);
}
#include <fstream.h>
#include <lib_client.hh>
int 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
LibraryClientHandlerclient_handler
;
// Obtain a handle to the ORB's registry
PCM_EXT::HandlerRegistery_ptr registry_handle =
try {
PCM_EXT::HandlerRegistry:::instance();
// Register the library event handler
registry_handle->reg_obj_client_handler(library_object,
}
&client_handler);
catch(constPMC_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(constPMC_EXT::NoHandler& excep
) {
cout << "No handler was registered" << endl;
}
catch(constPMC_EXT::InvalidObject& excep
) {
cout << "Invalid object reference" << endl;
}
return(1);
}
The ImplEventHandler
class.
class PCM_EXT
{
...
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.
ImplEventHandler Methods
The 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.
Example event handler class for the Library
object implementation.
class LibraryImplHandler : public PMC_EXT::ImplEventHandlerThe following code example shows the implementation for the
{
public:
voidbind
(const ConnectionInfo&, CORBA::Principal_ptr,
CORBA::Object_ptr);
voidunbind
(const ConnectionInfo&, CORBA::Principal_ptr,
CORBA::Object_ptr);
};
LibraryImplHandler
methods. You only need to define and provide method implementations for those events you wish to handle.
Method implementations for the LibraryImplHandler
class methods.
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; ...
};
HandlerRegistry Methods for Object Implementations
Call reg_obj_impl_handler
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.
Call reg_glob_impl_handler
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.Call
unreg_obj_impl_handler
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.
Call unreg_glob_impl_handler
to un-register 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 BOA's event handler registry. The following code listing shows the registration process for a global event handler.
Registering a global event handler for an object implementation.
#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");
The following code example shows how to register a per-object event handler. Both this and the previous example assume that the LibraryImplHandler class has been defined and implemented. Registering a per-object event handler for an object implementation.
// Define the impl_handler and registry instance
LibraryImplHandlerimpl_handler
;
PMC_EXT::HandlerRegistry_ptrregistry_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
LibraryImplHandlerimpl_handler
;
PMC_EXT::HandlerRegistry_ptrregistry_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;
}
...
}
Last Updated: 02/03/98 15:32:03