00001 // -*- C++ -*- 00002 00003 /** 00004 * @file ECG_UDP_Sender.h 00005 * 00006 * $Id: ECG_UDP_Sender.h 77001 2007-02-12 07:54:49Z johnnyw $ 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 (void); 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 00141 /// Connect or reconnect to the EC with the given subscriptions. 00142 /** 00143 * NOTE: if we are already connected to EC and a reconnection is 00144 * necessary, the EC must have reconnects enabled in order for this 00145 * method to succeed. 00146 */ 00147 void connect (const RtecEventChannelAdmin::ConsumerQOS &sub); 00148 00149 /// Deactivate from POA and disconnect from EC, if necessary. Shut 00150 /// down all sender components. 00151 /** 00152 * Calling this method may result in decrementing of the reference 00153 * count (due to deactivation) and deletion of the object. 00154 */ 00155 void shutdown (void); 00156 //@} 00157 00158 /// Accessors. 00159 //@{ 00160 /** 00161 * The sender may need to fragment the message, otherwise the 00162 * network may drop the packets. 00163 * Setting the MTU can fail if the value is too small (at least the 00164 * header + 8 bytes must fit). 00165 */ 00166 int mtu (CORBA::ULong mtu); 00167 CORBA::ULong mtu (void) const; 00168 00169 /// Get the local endpoint used to send the events. 00170 int get_local_addr (ACE_INET_Addr& addr); 00171 //@} 00172 00173 /// The PushConsumer methods. 00174 //@{ 00175 /// Invokes shutdown (), which may result in the object being deleted, if 00176 /// refcounting is used to manage its lifetime. 00177 virtual void disconnect_push_consumer (void); 00178 virtual void push (const RtecEventComm::EventSet &events); 00179 //@} 00180 00181 protected: 00182 00183 /// Constructor (protected). Clients can create new 00184 /// TAO_ECG_UDP_Sender objects using the static create() method. 00185 TAO_ECG_UDP_Sender (CORBA::Boolean crc = 0); 00186 00187 private: 00188 00189 /// Helpers for the connect() method. 00190 //@{ 00191 // Establishes connection to the Event Channel for the first time. 00192 void new_connect (const RtecEventChannelAdmin::ConsumerQOS& sub); 00193 00194 // Updates existing connection to the Event Channel. 00195 void reconnect (const RtecEventChannelAdmin::ConsumerQOS& sub); 00196 //@} 00197 00198 /// Proxy used to receive events from the Event Channel. 00199 RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; 00200 00201 /// Event Channel to which we act as a consumer. 00202 RtecEventChannelAdmin::EventChannel_var lcl_ec_; 00203 00204 /// We query this object to determine where the events should be sent. 00205 RtecUDPAdmin::AddrServer_var addr_server_; 00206 00207 /// Helper for fragmenting and sending cdr-encoded events using udp. 00208 TAO_ECG_CDR_Message_Sender cdr_sender_; 00209 00210 typedef TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command> 00211 ECG_Sender_Auto_Proxy_Disconnect; 00212 /// Manages our connection to Supplier Proxy. 00213 ECG_Sender_Auto_Proxy_Disconnect auto_proxy_disconnect_; 00214 }; 00215 00216 TAO_END_VERSIONED_NAMESPACE_DECL 00217 00218 #if defined(__ACE_INLINE__) 00219 #include "orbsvcs/Event/ECG_UDP_Sender.inl" 00220 #endif /* __ACE_INLINE__ */ 00221 00222 #include /**/ "ace/post.h" 00223 #endif /* TAO_ECG_UDP_SENDER_H */