ECG_UDP_Sender.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 /**
00004  * @file ECG_UDP_Sender.h
00005  *
00006  * ECG_UDP_Sender.h,v 1.15 2006/03/15 07:52:21 jtc Exp
00007  *
00008  *  @author Carlos O'Ryan (coryan@cs.wustl.edu)
00009  *  @author Marina Spivak (marina@atdesk.com)
00010  *
00011  * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and
00012  * other members of the DOC group. More details can be found in:
00013  *
00014  * http://doc.ece.uci.edu/~coryan/EC/index.html
00015  *
00016  * Define helper classes to propagate events between ECs using
00017  * either UDP or multicast.
00018  * The architecture is a bit complicated and deserves some
00019  * explanation: sending the events over UDP (or mcast) is easy, a
00020  * Consumer (TAO_ECG_UDP_Sender) subscribes for a certain set of
00021  * events, its push() method marshalls the event set into a CDR
00022  * stream that is sent using an ACE_SOCK_Dgram. The subscription
00023  * set and IP address can be configured.
00024  * Another helper class (TAO_ECG_UDP_Receiver) acts as a supplier of
00025  * events; it receives a callback when an event is available on an
00026  * ACE_SOCK_Dgram, it demarshalls the event and pushes it to the
00027  * EC.  Two ACE_Event_Handler classes are provided that can forward
00028  * the events to this Supplier: TAO_ECG_Mcast_EH can receive events
00029  * from a multicast group; TAO_ECG_UDP_EH can receive events from a
00030  * regular UDP socket.
00031  *
00032  * @todo The class makes an extra copy of the events, we need to
00033  * investigate if closer collaboration with its collocated EC could
00034  * be used to remove that copy.
00035  *
00036  */
00037 
00038 #ifndef TAO_ECG_UDP_SENDER_H
00039 #define TAO_ECG_UDP_SENDER_H
00040 #include /**/ "ace/pre.h"
00041 
00042 #include "orbsvcs/RtecUDPAdminS.h"
00043 
00044 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00045 # pragma once
00046 #endif /* ACE_LACKS_PRAGMA_ONCE */
00047 
00048 #include /**/ "orbsvcs/Event/event_serv_export.h"
00049 #include "orbsvcs/RtecEventChannelAdminS.h"
00050 
00051 #include "orbsvcs/Event/EC_Lifetime_Utils.h"
00052 #include "orbsvcs/Event/EC_Lifetime_Utils_T.h"
00053 #include "orbsvcs/Event/ECG_CDR_Message_Sender.h"
00054 
00055 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00056 class ACE_SOCK_Dgram;
00057 ACE_END_VERSIONED_NAMESPACE_DECL
00058 
00059 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00060 
00061 class TAO_ECG_UDP_Out_Endpoint;
00062 
00063 /**
00064  * @class TAO_ECG_UDP_Sender_Disconnect_Command
00065  *
00066  * @brief Disconnects consumer represented by @a proxy from the Event Channel.
00067  *
00068  * Utility class for use as a template argument to TAO_EC_Auto_Command.
00069  * TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command> manages
00070  * consumer connection to the Event Channel, automatically disconnecting from
00071  * @a proxy in its destructor, if necessary.
00072  */
00073 class TAO_RTEvent_Serv_Export TAO_ECG_UDP_Sender_Disconnect_Command
00074 {
00075 public:
00076   TAO_ECG_UDP_Sender_Disconnect_Command (void);
00077   TAO_ECG_UDP_Sender_Disconnect_Command (
00078               RtecEventChannelAdmin::ProxyPushSupplier_ptr proxy);
00079 
00080   TAO_ECG_UDP_Sender_Disconnect_Command (
00081               const TAO_ECG_UDP_Sender_Disconnect_Command & rhs);
00082 
00083   TAO_ECG_UDP_Sender_Disconnect_Command &
00084    operator= (const TAO_ECG_UDP_Sender_Disconnect_Command & rhs);
00085 
00086   void execute (ACE_ENV_SINGLE_ARG_DECL);
00087 
00088 private:
00089 
00090   RtecEventChannelAdmin::ProxyPushSupplier_var proxy_;
00091 };
00092 
00093 
00094 /**
00095  * @class TAO_ECG_UDP_Sender
00096  *
00097  * @brief Send events received from a "local" EC using UDP.
00098  *        NOT THREAD-SAFE.
00099  * This class connect as a consumer to an EventChannel
00100  * and forwards the events it receives from that EC using UDP.
00101  *
00102  */
00103 class TAO_RTEvent_Serv_Export TAO_ECG_UDP_Sender :
00104   public virtual POA_RtecEventComm::PushConsumer,
00105   public TAO_EC_Deactivated_Object
00106 {
00107 public:
00108 
00109   /// Initialization and termination methods.
00110   //@{
00111 
00112   /// Create a new TAO_ECG_UDP_Sender object.
00113   /// (Constructor access is restricted to insure that all
00114   /// TAO_ECG_UDP_Sender objects are heap-allocated.)
00115   static TAO_EC_Servant_Var<TAO_ECG_UDP_Sender> create (CORBA::Boolean crc = 0);
00116 
00117   ~TAO_ECG_UDP_Sender (void);
00118 
00119   /**
00120    * @param lcl_ec Event Channel to which we will act as a consumer of events.
00121    * @param addr_server Address server used to obtain event type to
00122    *        multicast group mapping.
00123    * @param endpoint_rptr Endpoint for sending udp/multicast messages.
00124    *        Endpoint's dgram must be open!
00125    *
00126    * To insure proper resource clean up, if init () is successful,
00127    * shutdown () must be called when the sender is no longer needed.
00128    * This is done by disconnect_push_consumer() method.  If
00129    * disconnect_push_consumer() will not be called, it is the
00130    * responsibility of the user.
00131    * Furthermore, if shutdown() is not explicitly called by
00132    * either disconnect_push_consumer () or the user, the sender
00133    * will clean up the resources in its destructor, however, certain
00134    * entities involved in cleanup must still exist at that point,
00135    * e.g., POA.
00136    */
00137   void init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec,
00138              RtecUDPAdmin::AddrServer_ptr addr_server,
00139              TAO_ECG_Refcounted_Endpoint endpoint_rptr
00140              ACE_ENV_ARG_DECL);
00141 
00142   /// Connect or reconnect to the EC with the given subscriptions.
00143   /**
00144    * NOTE: if we are already connected to EC and a reconnection is
00145    * necessary, the EC must have reconnects enabled in order for this
00146    * method to succeed.
00147    */
00148   void connect (const RtecEventChannelAdmin::ConsumerQOS &sub
00149                 ACE_ENV_ARG_DECL);
00150 
00151   /// Deactivate from POA and disconnect from EC, if necessary.  Shut
00152   /// down all sender components.
00153   /**
00154    * Calling this method may result in decrementing of the reference
00155    * count (due to deactivation) and deletion of the object.
00156    */
00157   void shutdown (ACE_ENV_SINGLE_ARG_DECL);
00158   //@}
00159 
00160   /// Accessors.
00161   //@{
00162   /**
00163    * The sender may need to fragment the message, otherwise the
00164    * network may drop the packets.
00165    * Setting the MTU can fail if the value is too small (at least the
00166    * header + 8 bytes must fit).
00167    */
00168   int mtu (CORBA::ULong mtu);
00169   CORBA::ULong mtu (void) const;
00170 
00171   /// Get the local endpoint used to send the events.
00172   int get_local_addr (ACE_INET_Addr& addr);
00173   //@}
00174 
00175   /// The PushConsumer methods.
00176   //@{
00177   /// Invokes shutdown (), which may result in the object being deleted, if
00178   /// refcounting is used to manage its lifetime.
00179   virtual void disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL)
00180       ACE_THROW_SPEC ((CORBA::SystemException));
00181   virtual void push (const RtecEventComm::EventSet &events
00182                      ACE_ENV_ARG_DECL)
00183       ACE_THROW_SPEC ((CORBA::SystemException));
00184   //@}
00185 
00186 protected:
00187 
00188   /// Constructor (protected).  Clients can create new
00189   /// TAO_ECG_UDP_Sender objects using the static create() method.
00190   TAO_ECG_UDP_Sender (CORBA::Boolean crc = 0);
00191 
00192 private:
00193 
00194   /// Helpers for the connect() method.
00195   //@{
00196   // Establishes connection to the Event Channel for the first time.
00197   void new_connect (const RtecEventChannelAdmin::ConsumerQOS& sub
00198                     ACE_ENV_ARG_DECL);
00199 
00200   // Updates existing connection to the Event Channel.
00201   void reconnect (const RtecEventChannelAdmin::ConsumerQOS& sub
00202                   ACE_ENV_ARG_DECL);
00203   //@}
00204 
00205   /// Proxy used to receive events from the Event Channel.
00206   RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_;
00207 
00208   /// Event Channel to which we act as a consumer.
00209   RtecEventChannelAdmin::EventChannel_var lcl_ec_;
00210 
00211   /// We query this object to determine where the events should be sent.
00212   RtecUDPAdmin::AddrServer_var addr_server_;
00213 
00214   /// Helper for fragmenting and sending cdr-encoded events using udp.
00215   TAO_ECG_CDR_Message_Sender cdr_sender_;
00216 
00217   typedef TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command>
00218   ECG_Sender_Auto_Proxy_Disconnect;
00219   /// Manages our connection to Supplier Proxy.
00220   ECG_Sender_Auto_Proxy_Disconnect auto_proxy_disconnect_;
00221 };
00222 
00223 TAO_END_VERSIONED_NAMESPACE_DECL
00224 
00225 #if defined(__ACE_INLINE__)
00226 #include "orbsvcs/Event/ECG_UDP_Sender.inl"
00227 #endif /* __ACE_INLINE__ */
00228 
00229 #include /**/ "ace/post.h"
00230 #endif /* TAO_ECG_UDP_SENDER_H */

Generated on Thu Nov 9 13:11:11 2006 for TAO_RTEvent by doxygen 1.3.6