00001 //////////////////////////////////////////////////////////////////////////////// 00002 /*! \file AddressClient.h 00003 * \brief Declares the class that communicates with an address server. 00004 * \author $Author: rsharo $ 00005 * \version $Revision: 1.1 $ 00006 * \date $Date: 2004/04/07 13:45:04 $ 00007 */////////////////////////////////////////////////////////////////////////////// 00008 #ifndef ADDRESS_CLIENT_H 00009 #define ADDRESS_CLIENT_H 00010 00011 #include "ace/INET_Addr.h" 00012 #include "ace/SOCK_Dgram.h" 00013 #include "ace/Reactor.h" 00014 00015 #include "ace/Synch_T.h" 00016 00017 #include <map> 00018 #include <list> 00019 #include <vector> 00020 00021 #include "Comm/ReplyQueue.h" 00022 00023 // 00024 // A reactor-based class that knows how to communicate with an AddressServer. 00025 // 00026 // This class is a fundamental part of the MessageClient/MessageServer scheme. 00027 // Message clients are user-derived classes that send and receive messages 00028 // on the network. Message clients carry an integer identifier that 00029 // determines which messages they are to receive. Since clients can be 00030 // distributed over a network, a means is needed to keep track of which 00031 // message clients are at which IP addresses -- or more specifically which 00032 // IP addresses are interested in which messages. 00033 // An address server is an object that holds the mappings from message ID 00034 // to IP address (called bindings). The address server will typically 00035 // be located at a multicast address so it can be physically located anywhere 00036 // on the network. 00037 // 00038 // AddressClient is a class that manages communication with the address server. 00039 // Through AddressClient method calls, bindings can be queried, added or 00040 // removed from an address server. A message server depends on its 00041 // AddressClient to route incoming and outgoing messages. 00042 // 00043 // The AddressClient class is a subclass of ACE_Event_Handler, and must 00044 // be registered with an ACE_Reactor to function properly. 00045 class AddressClient : public ACE_Event_Handler 00046 { 00047 public: 00048 // 00049 // The data type that hold a list of IP addresses. 00050 typedef std::vector<ACE_INET_Addr> AddrList_t; 00051 00052 // 00053 // Constructor. 00054 // Given the IP address of the address server, this 00055 // method constructs an AddressClient. The client 00056 // must be registered with a reactor before it will be useful, 00057 // however. 00058 explicit AddressClient (const ACE_INET_Addr &addrServer); 00059 00060 // 00061 // Destroys the AddressClient. The client should have been 00062 // deregistered from its reactor (if any) before this method 00063 // is called. 00064 ~AddressClient (void); 00065 00066 // 00067 // Connect this object to a reactor. 00068 // This must be done before any server communication is initiated. 00069 // Returns zero on success and -1 on failure. 00070 int RegisterWithReactor(ACE_Reactor &theReactor); 00071 00072 // 00073 // Disconnects this object from the reactor. 00074 // This effectively disables the AddressClient. This method 00075 // should be called before destroying the object. 00076 // The "immediate" flag determines whether the call should 00077 // return immediately or not. If set to false, then the 00078 // AddressClient will attempt to remove itself from the 00079 // AddressServer's notification list. The "immediate" flag 00080 // will typically only be set if the client needs to shut 00081 // down quickly or if the AddressServer is shutting down as well. 00082 // Returns zero on success and -1 on failure. 00083 int RemoveFromReactor(ACE_Reactor &theReactor, bool immediate=false); 00084 00085 // 00086 // Sets the amount of time a server call will wait 00087 // before giving up and reporting an error. A value of zero 00088 // means "wait forever". 00089 void SetTimeout(const ACE_Time_Value &tv); 00090 00091 // 00092 // Queries the server to see if it is responding. 00093 // The client will wait up to its specified timeout interval 00094 // before returning a failure. 00095 // Returns zero on success and -1 on failure. 00096 int PingServer(); 00097 00098 // 00099 // Registers the AddressClient to be notified when the server's 00100 // bindings change. This is necessary to know when to invalidate 00101 // the AddressClient's cache. This method should be called one time 00102 // after the AddressClient is registered with the reactor, but before 00103 // any bindings are requested. 00104 int RegisterServerCallback(); 00105 00106 // 00107 // Removes the AddressClient from the AddressServer's notification list. 00108 // The AddressClient will no longer be notified when the server's 00109 // bindings change. This method is automatically called from 00110 // RemoveFromReactor() unless the "immediate" flag was set. 00111 // Calling this method is typically a precursor to shutdown. 00112 // Returns zero on success and -1 on failure. 00113 int RemoveServerCallback(); 00114 00115 // 00116 // Clears the AddressServer's notification list. 00117 // No AddressClient objects will be notified any longer when 00118 // the server's bindings change. Note that this method does not 00119 // notify the other AddressClients that this has happened. 00120 // This method would typically only be called when the AddressServer 00121 // is to be reset from an indeterminate state (such as after a restart) 00122 // and all other clients have been shut down. 00123 // Returns zero on success and -1 on failure. 00124 int ClearServerCallbacks(); 00125 00126 // 00127 // Retrieves a list of IP addresses bound to a given message ID. 00128 // The MessageServer will call this method any time a message 00129 // is sent. Messages destined for a given ID will be routed 00130 // to each IP address in the binding list. 00131 // Returns zero on success and -1 on failure. 00132 int GetBindings(u_int dest, AddrList_t &theList); 00133 00134 // 00135 // Adds an IP address/ID binding to the AddressServer. 00136 // This method is called when a MessageClient is added to the 00137 // MessageServer with a previously-unused ID. The AddressServer 00138 // will add the IP address from the binding string to its list 00139 // of addresses for the given ID. 00140 // The binding string is of standard ACE format: 00141 // "<hostname>:<port>" 00142 // Returns zero on success and -1 on failure. 00143 int AddBinding(u_int id, const char *binding); 00144 00145 // 00146 // Removes an IP address/ID binding from the AddressServer. 00147 // This method is called when a MessageClient is removed from the 00148 // MessageServer and the ID is otherwise-unused. The AddressServer 00149 // will remove the IP address from the binding string from its list 00150 // of addresses for the given ID. 00151 // The binding string is of standard ACE format: 00152 // "<hostname>:<port>" 00153 // Returns zero on success and -1 on failure. 00154 int RemoveBinding(u_int id, const char *binding); 00155 00156 // 00157 // Clears all IP address/ID bindings from the AddressServer. 00158 // This method would typically only be called when the AddressServer 00159 // is being reset from an indeterminate state (such as after a restart) 00160 // and no MessageClients are currently registered. 00161 // Returns zero on success and -1 on failure. 00162 int ClearBindings(); 00163 00164 // 00165 // Implementation of the handle_input() method derived from 00166 // ACE_Event_Handler. This method processes messages sent from the 00167 // address server. 00168 virtual int handle_input (ACE_HANDLE fd); 00169 00170 // 00171 // Implementation of the get_handle() method derived from 00172 // ACE_Event_Handler. This method returns a handle to the AddressClient's 00173 // UDP socket. 00174 virtual ACE_HANDLE get_handle (void) const; 00175 00176 protected: 00177 00178 // 00179 // The data structure used to hold cached bindings. 00180 typedef std::map<u_int, AddrList_t> BindMap_t; 00181 // 00182 // The internal structure that holds individual binding pairs. 00183 typedef BindMap_t::value_type BindValue_t; 00184 00185 // 00186 // The data type of the queue used to serialize the replies 00187 // expected after AddressServer commands. 00188 typedef ReplyQueue<std::string, ACE_SYNCH> ReplyQueue_t; 00189 00190 // 00191 // Sends a command to the AddressServer via UDP/IP. Note that all 00192 // AddressServer commands are in the form of ASCII strings. If a reply 00193 // is received before the AddressClient's timeout period expires, 00194 // it is placed in the "reply" argument. 00195 // Returns zero if command was send and a reply was received within 00196 // the timeout period, -1 otherwise. 00197 int SendCommand(const char *str, std::string &reply); 00198 00199 private: 00200 ACE_INET_Addr m_addrServer; 00201 00202 char m_buf[BUFSIZ]; 00203 ACE_SOCK_Dgram m_socket; 00204 00205 ACE_Thread_Mutex m_bindingMutex; 00206 BindMap_t m_bindings; 00207 00208 ACE_Thread_Mutex m_pendingReplyMutex; 00209 ReplyQueue_t m_pendingReplyQueue; 00210 00211 long m_notificationID; 00212 00213 ACE_Thread_Mutex m_pingMutex; 00214 ACE_Thread_Condition<ACE_Thread_Mutex> m_pingCondition; 00215 00216 ACE_Time_Value m_timeout; 00217 }; 00218 00219 #endif // ADDRESS_CLIENT_H