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 */