00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CClientListener.h"
00016 #include "CClientProxy.h"
00017 #include "CClientProxyUnknown.h"
00018 #include "CPacketStreamFilter.h"
00019 #include "IStreamFilterFactory.h"
00020 #include "IDataSocket.h"
00021 #include "IListenSocket.h"
00022 #include "ISocketFactory.h"
00023 #include "XSocket.h"
00024 #include "CLog.h"
00025 #include "IEventQueue.h"
00026 #include "TMethodEventJob.h"
00027
00028
00029
00030
00031
00032 CEvent::Type CClientListener::s_connectedEvent = CEvent::kUnknown;
00033
00034 CClientListener::CClientListener(const CNetworkAddress& address,
00035 ISocketFactory* socketFactory,
00036 IStreamFilterFactory* streamFilterFactory) :
00037 m_socketFactory(socketFactory),
00038 m_streamFilterFactory(streamFilterFactory)
00039 {
00040 assert(m_socketFactory != NULL);
00041
00042 try {
00043
00044 m_listen = m_socketFactory->createListen();
00045
00046
00047 LOG((CLOG_DEBUG1 "binding listen socket"));
00048 m_listen->bind(address);
00049 }
00050 catch (XSocketAddressInUse&) {
00051 delete m_listen;
00052 delete m_socketFactory;
00053 delete m_streamFilterFactory;
00054 throw;
00055 }
00056 catch (XBase&) {
00057 delete m_listen;
00058 delete m_socketFactory;
00059 delete m_streamFilterFactory;
00060 throw;
00061 }
00062 LOG((CLOG_DEBUG1 "listening for clients"));
00063
00064
00065 EVENTQUEUE->adoptHandler(IListenSocket::getConnectingEvent(), m_listen,
00066 new TMethodEventJob<CClientListener>(this,
00067 &CClientListener::handleClientConnecting));
00068 }
00069
00070 CClientListener::~CClientListener()
00071 {
00072 LOG((CLOG_DEBUG1 "stop listening for clients"));
00073
00074
00075 for (CNewClients::iterator index = m_newClients.begin();
00076 index != m_newClients.end(); ++index) {
00077 CClientProxyUnknown* client = *index;
00078 EVENTQUEUE->removeHandler(
00079 CClientProxyUnknown::getSuccessEvent(), client);
00080 EVENTQUEUE->removeHandler(
00081 CClientProxyUnknown::getFailureEvent(), client);
00082 EVENTQUEUE->removeHandler(
00083 CClientProxy::getDisconnectedEvent(), client);
00084 delete client;
00085 }
00086
00087
00088 CClientProxy* client = getNextClient();
00089 while (client != NULL) {
00090 delete client;
00091 client = getNextClient();
00092 }
00093
00094 EVENTQUEUE->removeHandler(IListenSocket::getConnectingEvent(), m_listen);
00095 delete m_listen;
00096 delete m_socketFactory;
00097 delete m_streamFilterFactory;
00098 }
00099
00100 CClientProxy*
00101 CClientListener::getNextClient()
00102 {
00103 CClientProxy* client = NULL;
00104 if (!m_waitingClients.empty()) {
00105 client = m_waitingClients.front();
00106 m_waitingClients.pop_front();
00107 EVENTQUEUE->removeHandler(CClientProxy::getDisconnectedEvent(), client);
00108 }
00109 return client;
00110 }
00111
00112 CEvent::Type
00113 CClientListener::getConnectedEvent()
00114 {
00115 return CEvent::registerTypeOnce(s_connectedEvent,
00116 "CClientListener::connected");
00117 }
00118
00119 void
00120 CClientListener::handleClientConnecting(const CEvent&, void*)
00121 {
00122
00123 IStream* stream = m_listen->accept();
00124 if (stream == NULL) {
00125 return;
00126 }
00127 LOG((CLOG_NOTE "accepted client connection"));
00128
00129
00130 if (m_streamFilterFactory != NULL) {
00131 stream = m_streamFilterFactory->create(stream, true);
00132 }
00133 stream = new CPacketStreamFilter(stream, true);
00134
00135
00136 CClientProxyUnknown* client = new CClientProxyUnknown(stream, 30.0);
00137 m_newClients.insert(client);
00138
00139
00140 EVENTQUEUE->adoptHandler(CClientProxyUnknown::getSuccessEvent(), client,
00141 new TMethodEventJob<CClientListener>(this,
00142 &CClientListener::handleUnknownClient, client));
00143 EVENTQUEUE->adoptHandler(CClientProxyUnknown::getFailureEvent(), client,
00144 new TMethodEventJob<CClientListener>(this,
00145 &CClientListener::handleUnknownClient, client));
00146 }
00147
00148 void
00149 CClientListener::handleUnknownClient(const CEvent&, void* vclient)
00150 {
00151 CClientProxyUnknown* unknownClient =
00152 reinterpret_cast<CClientProxyUnknown*>(vclient);
00153
00154
00155 assert(m_newClients.count(unknownClient) == 1);
00156
00157
00158 CClientProxy* client = unknownClient->orphanClientProxy();
00159 if (client != NULL) {
00160
00161 m_waitingClients.push_back(client);
00162 EVENTQUEUE->addEvent(CEvent(getConnectedEvent(), this));
00163
00164
00165 EVENTQUEUE->adoptHandler(CClientProxy::getDisconnectedEvent(), client,
00166 new TMethodEventJob<CClientListener>(this,
00167 &CClientListener::handleClientDisconnected,
00168 client));
00169 }
00170
00171
00172 EVENTQUEUE->removeHandler(CClientProxyUnknown::getSuccessEvent(), client);
00173 EVENTQUEUE->removeHandler(CClientProxyUnknown::getFailureEvent(), client);
00174 m_newClients.erase(unknownClient);
00175 delete unknownClient;
00176 }
00177
00178 void
00179 CClientListener::handleClientDisconnected(const CEvent&, void* vclient)
00180 {
00181 CClientProxy* client = reinterpret_cast<CClientProxy*>(vclient);
00182
00183
00184 for (CWaitingClients::iterator i = m_waitingClients.begin(),
00185 n = m_waitingClients.end(); i != n; ++i) {
00186 if (*i == client) {
00187 m_waitingClients.erase(i);
00188 EVENTQUEUE->removeHandler(CClientProxy::getDisconnectedEvent(),
00189 client);
00190 delete client;
00191 break;
00192 }
00193 }
00194 }