From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/net__manager_8cpp-source.html | 616 +++++++++++++++++++++++++ 1 file changed, 616 insertions(+) create mode 100644 docs/doxygen/nel/net__manager_8cpp-source.html (limited to 'docs/doxygen/nel/net__manager_8cpp-source.html') diff --git a/docs/doxygen/nel/net__manager_8cpp-source.html b/docs/doxygen/nel/net__manager_8cpp-source.html new file mode 100644 index 00000000..19f070f8 --- /dev/null +++ b/docs/doxygen/nel/net__manager_8cpp-source.html @@ -0,0 +1,616 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

net_manager.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 
+00028 
+00029 /**************************************************************************
+00030 ********************* THIS CLASS IS DEPRECATED ****************************
+00031 **************************************************************************/
+00032 
+00033 
+00034 
+00035 
+00036 #include "stdnet.h"
+00037 
+00038 #include "nel/misc/string_id_array.h"
+00039 #include "nel/misc/time_nl.h"
+00040 
+00041 #include "nel/net/naming_client.h"
+00042 
+00043 #include "nel/net/callback_client.h"
+00044 #include "nel/net/callback_server.h"
+00045 
+00046 #include "nel/net/naming_client.h"
+00047 
+00048 #include "nel/net/net_manager.h"
+00049 
+00050 using namespace std;
+00051 using namespace NLMISC;
+00052 
+00053 namespace NLNET {
+00054 
+00055 
+00056 CNetManager::TBaseMap   CNetManager::_BaseMap;
+00057 
+00058 CCallbackNetBase::TRecordingState       CNetManager::_RecordingState;
+00059 
+00060 TTime CNetManager::_NextUpdateTime = 0;
+00061 
+00062 static void nmNewConnection (TSockId from, void *arg)
+00063 {
+00064         nlassert (arg != NULL);
+00065         CBaseStruct *basest = (CBaseStruct *)arg;
+00066 
+00067         nldebug("HNETL4: nmNewConnection() from service '%s'", basest->Name.c_str ());
+00068 
+00069         // call the client callback if necessary
+00070         if (basest->ConnectionCallback != NULL)
+00071                 basest->ConnectionCallback (basest->Name, from, basest->ConnectionCbArg);
+00072 }
+00073 
+00074 static void nmNewDisconnection (TSockId from, void *arg)
+00075 {
+00076         nlassert (arg != NULL);
+00077         CBaseStruct *basest = (CBaseStruct *)arg;
+00078 
+00079         nldebug("HNETL4: nmNewDisconnection() from service '%s'", basest->Name.c_str ());
+00080 
+00081         // call the client callback if necessary
+00082         if (basest->DisconnectionCallback != NULL)
+00083                 basest->DisconnectionCallback (basest->Name, from, basest->DisconnectionCbArg);
+00084 
+00086 
+00087         // on a client, we have to clear the associations
+00088         if (basest->Type != CBaseStruct::Server)
+00089         {
+00090                 nlassert (basest->NetBase.size() == 1);
+00091                 basest->NetBase[0]->getSIDA ().clear ();
+00092         }
+00093 }
+00094 
+00095 
+00096 // find a not connected callbackclient or create a new one and connect to the Addr
+00097 void CNetManager::createConnection(CBaseStruct &Base, const CInetAddress &Addr, const string& name)
+00098 {
+00099         uint i;
+00100         for (i = 0; i < Base.NetBase.size (); i++)
+00101         {
+00102                 if (!Base.NetBase[i]->connected ())
+00103                 {
+00104                         break;
+00105                 }
+00106         }
+00107         if (i == Base.NetBase.size ())
+00108         {
+00109                 CCallbackClient *cc = new CCallbackClient( _RecordingState, name+string(".nmr") );
+00110                 Base.NetBase.push_back (cc);
+00111         }
+00112         
+00113         CCallbackClient *cc = dynamic_cast<CCallbackClient *>(Base.NetBase[i]);
+00114 
+00115         cc->CCallbackNetBase::setDisconnectionCallback (nmNewDisconnection, (void*) &Base);
+00116 
+00117         try
+00118         {
+00119                 cc->connect (Addr);
+00120 
+00121                 if (Base.ConnectionCallback != NULL)
+00122                         Base.ConnectionCallback (Base.Name, cc->getSockId(), Base.ConnectionCbArg);
+00123         }
+00124         catch (ESocketConnectionFailed &e)
+00125         {
+00126                 nlinfo ("HNETL4: can't connect now (%s)", e.what ());
+00127         }
+00128 }
+00129 
+00130 
+00131 void RegistrationBroadcast (const std::string &name, TServiceId sid, const vector<CInetAddress> &addr)
+00132 {
+00133         nldebug("HNETL4: RegistrationBroadcast() of service %s-%hu", name.c_str (), (uint16)sid);
+00134 
+00135         // find if this new service is interesting
+00136         for (CNetManager::ItBaseMap itbm = CNetManager::_BaseMap.begin (); itbm != CNetManager::_BaseMap.end (); itbm++)
+00137         {
+00138                 if ((*itbm).second.Type == CBaseStruct::Client && !(*itbm).second.NetBase[0]->connected())
+00139                 {
+00140                         if (name == (*itbm).first)
+00141                         {
+00142                                 // ok! it's cool, the service is here, go and connect to him!
+00143 // ace warning don't work if more than one connection
+00144                                 CNetManager::createConnection ((*itbm).second, addr[0], name);
+00145                         }
+00146                 }
+00147                 else if ((*itbm).second.Type == CBaseStruct::Group)
+00148                 {
+00149                         // ok, it's a group, try to see if it wants this!
+00150                         for (uint i = 0; i < (*itbm).second.ServiceNames.size (); i++)
+00151                         {
+00152                                 if ((*itbm).second.ServiceNames[i] == name)
+00153                                 {
+00154 // ace warning don't work if more than one connection
+00155                                         CNetManager::createConnection ((*itbm).second, addr[0], name);
+00156                                         break;
+00157                                 }
+00158                         }
+00159                 }
+00160         }
+00161 
+00162 }
+00163 
+00164 static void UnregistrationBroadcast (const std::string &name, TServiceId sid, const vector<CInetAddress> &addr)
+00165 {
+00166         nldebug("HNETL4: UnregistrationBroadcast() of service %s-%hu", name.c_str (), (uint16)sid);
+00167 }
+00168 
+00169 void CNetManager::init (const CInetAddress *addr, CCallbackNetBase::TRecordingState rec )
+00170 {
+00171         if (addr == NULL) return;
+00172 
+00173         _RecordingState = rec;
+00174 
+00175         // connect to the naming service (may generate a ESocketConnectionFailed exception)
+00176 
+00177         vector<CInetAddress> laddr = CInetAddress::localAddresses();
+00178         CNamingClient::connect( *addr, _RecordingState, laddr );
+00179 
+00180         // connect the callback to know when a new service comes in or goes down
+00181         CNamingClient::setRegistrationBroadcastCallback (RegistrationBroadcast);
+00182         CNamingClient::setUnregistrationBroadcastCallback (UnregistrationBroadcast);
+00183 }
+00184 
+00185 void CNetManager::release ()
+00186 {
+00187         if (CNamingClient::connected ())
+00188                 CNamingClient::disconnect ();
+00189 
+00190         for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00191         {
+00192                 for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00193                 {
+00194                         (*itbm).second.NetBase[i]->disconnect ();
+00195                         delete (*itbm).second.NetBase[i];
+00196                 }
+00197         }
+00198         _BaseMap.clear ();
+00199 }
+00200 
+00201 void CNetManager::addServer (const std::string &serviceName, uint16 servicePort, bool external)
+00202 {
+00203         TServiceId sid = 0;
+00204         addServer (serviceName, servicePort, sid, external);
+00205 }
+00206 
+00207 void CNetManager::addServer (const std::string &serviceName, uint16 servicePort, TServiceId &sid, bool external)
+00208 {
+00209         nldebug ("HNETL4: Adding server '%s' in CNetManager", serviceName.c_str ());
+00210         ItBaseMap itbm = find (serviceName);
+00211 
+00212         // check if it's a new server
+00213         nlassert ((*itbm).second.NetBase.empty());
+00214         
+00215         CCallbackServer *cs = new CCallbackServer( _RecordingState, serviceName+string(".nmr") );
+00216         (*itbm).second.NetBase.push_back (cs);
+00217 
+00218         (*itbm).second.Type = CBaseStruct::Server;
+00219 
+00220         // install the server
+00221         
+00222         cs->setConnectionCallback (nmNewConnection, (void*) &((*itbm).second));
+00223         cs->CCallbackNetBase::setDisconnectionCallback (nmNewDisconnection, (void*) &((*itbm).second));
+00224 
+00225         if (servicePort == 0)
+00226         {
+00227                 nlassert (CNamingClient::connected ());
+00228                 servicePort = CNamingClient::queryServicePort ();
+00229         }
+00230 
+00231         cs->init (servicePort);
+00232 
+00233         // register the server to the naming service if we are connected to Naming Service
+00234 
+00235         if (CNamingClient::connected () && !external)
+00236         {
+00237                 //CInetAddress addr = CInetAddress::localHost ();
+00238                 //addr.setPort (servicePort);
+00239                 vector<CInetAddress> addr = CInetAddress::localAddresses();
+00240                 for (uint i = 0; i < addr.size(); i++)
+00241                         addr[i].setPort(servicePort);
+00242 
+00243                 if (sid == 0)
+00244                 {
+00245                         CNamingClient::registerService (serviceName, addr, sid);
+00246                 }
+00247                 else
+00248                 {
+00249                         CNamingClient::registerServiceWithSId (serviceName, addr, sid);
+00250                 }
+00251         }
+00252         nlinfo ("HNETL4: Server '%s' added, registered and listen to port %hu", serviceName.c_str (), servicePort);
+00253 }
+00254 
+00255 
+00256 void CNetManager::addClient (const std::string &serviceName, const std::string &addr, bool autoRetry)
+00257 {
+00258         nldebug ("HNETL4: Adding client '%s' with addr '%s' in CNetManager", serviceName.c_str (), addr.c_str());
+00259         ItBaseMap itbm = find (serviceName);
+00260         
+00261         // it's a new client, add the connection
+00262         (*itbm).second.Type = CBaseStruct::ClientWithAddr;
+00263         (*itbm).second.AutoRetry = autoRetry;
+00264 
+00265         if ((*itbm).second.ServiceNames.empty())
+00266         {
+00267                 (*itbm).second.ServiceNames.push_back(addr);
+00268         }
+00269         else
+00270         {
+00271                 (*itbm).second.ServiceNames[0] = addr;
+00272         }
+00273 
+00274         nlassert ((*itbm).second.NetBase.size() < 2);
+00275 
+00276         createConnection ((*itbm).second, addr, serviceName);
+00277 }
+00278 
+00279 
+00280 void CNetManager::addClient (const std::string &serviceName)
+00281 {
+00282         nlassert (CNamingClient::connected ());
+00283         nldebug ("HNETL4: Adding client '%s' in CNetManager", serviceName.c_str ());
+00284         ItBaseMap itbm = find (serviceName);
+00285         
+00286         // check if it's a new client
+00287         nlassert ((*itbm).second.NetBase.empty());
+00288 
+00289         CCallbackClient *cc = new CCallbackClient( _RecordingState, serviceName+string(".nmr") ); // ? - would not work if several clients with the same name
+00290         (*itbm).second.NetBase.push_back (cc);
+00291 
+00292         (*itbm).second.Type = CBaseStruct::Client;
+00293 
+00294         cc->CCallbackNetBase::setDisconnectionCallback (nmNewDisconnection, (void*) &((*itbm).second));
+00295 
+00296         // find the service in the naming_service and connect if exists
+00297         if (CNamingClient::lookupAndConnect (serviceName, *cc))
+00298         {
+00299                 // call the user that we are connected
+00300                 if ((*itbm).second.ConnectionCallback != NULL)
+00301                         (*itbm).second.ConnectionCallback (serviceName, cc->getSockId(), (*itbm).second.ConnectionCbArg);
+00302         }
+00303 }
+00304 
+00305 
+00306 
+00307 void CNetManager::addGroup (const std::string &groupName, const std::string &serviceName)
+00308 {
+00309         nlassert (CNamingClient::connected ());
+00310         nldebug ("HNETL4: Adding '%s' to group '%s' in CNetManager", serviceName.c_str (), groupName.c_str());
+00311         ItBaseMap itbm = find (groupName);
+00312 
+00313         (*itbm).second.Type = CBaseStruct::Group;
+00314 
+00315         // check if you don't already add this service in this group
+00316         vector<string>::iterator it = std::find ((*itbm).second.ServiceNames.begin(), (*itbm).second.ServiceNames.end(), serviceName);
+00317         nlassert (it == (*itbm).second.ServiceNames.end());
+00318 
+00319         (*itbm).second.ServiceNames.push_back(serviceName);
+00320 
+00321 
+00322         // find the service in the naming_service and connect if exists
+00323         vector<CInetAddress> addrs;
+00324         CNamingClient::lookupAll (serviceName, addrs);
+00325 
+00326         // connect to all these services
+00327         for (uint i = 0; i < addrs.size (); i++)
+00328         {
+00329                 createConnection ((*itbm).second, addrs[i], serviceName);
+00330         }
+00331 }
+00332 
+00333 
+00334 
+00335 NLMISC::CStringIdArray &CNetManager::getSIDA (const std::string &serviceName)
+00336 {
+00337         nldebug ("HNETL4: getSIDA() for service '%s'", serviceName.c_str ());
+00338         ItBaseMap itbm = find (serviceName);
+00339 
+00340         // in case of group, we can return association only if there s only one service on it
+00341         nlassert ((*itbm).second.NetBase.size() == 1);
+00342 
+00343         return (*itbm).second.NetBase[0]->getSIDA ();
+00344 }
+00345 
+00346 void CNetManager::addCallbackArray (const std::string &serviceName, const TCallbackItem *callbackarray, NLMISC::CStringIdArray::TStringId arraysize)
+00347 {
+00348         nldebug ("HNETL4: addingCallabckArray() for service '%s'", serviceName.c_str ());
+00349         ItBaseMap itbm = find (serviceName);
+00350         for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00351         {
+00352 //              if ((*itbm).second.NetBase[i]->connected())
+00353                 (*itbm).second.NetBase[i]->addCallbackArray (callbackarray, arraysize);
+00354         }
+00355 }
+00356 
+00357 void CNetManager::update (TTime timeout)
+00358 {
+00359 //      nldebug ("HNETL4: update()");
+00360 
+00361 //      sint64 p1 = CTime::getPerformanceTime ();
+00362 
+00363         TTime t0 = CTime::getLocalTime ();
+00364 
+00365         if (timeout > 0)
+00366         {
+00367                 if (_NextUpdateTime == 0)
+00368                 {
+00369                         _NextUpdateTime = t0 + timeout;
+00370                 }
+00371                 else
+00372                 {
+00373                         TTime err = t0 - _NextUpdateTime;
+00374                         _NextUpdateTime += timeout;
+00375 
+00376                         // if we are too late, resync to the next value
+00377                         while (err > timeout)
+00378                         {
+00379                                 err -= timeout;
+00380                                 _NextUpdateTime += timeout;
+00381                         }
+00382                         
+00383                         timeout -= err;
+00384                         if (timeout < 0) timeout = 0;
+00385                 }
+00386         }
+00387         
+00388 //      sint64 p2 = CTime::getPerformanceTime ();
+00389 
+00390         while (true)
+00391         {
+00392                 for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00393                 {
+00394                         for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00395                         {
+00397                                 // we get and treat all messages in this connection
+00398                                 (*itbm).second.NetBase[i]->update (0);
+00399                                 if ((*itbm).second.NetBase[i]->connected())
+00400                                 {
+00401                                         // if connected, update
+00402 //                                      (*itbm).second.NetBase[i]->update ();
+00403                                 }
+00404                                 else
+00405                                 {
+00406                                         static TTime lastTime = CTime::getLocalTime();
+00407                                         if (CTime::getLocalTime() - lastTime > 5000)
+00408                                         {
+00409                                                 lastTime = CTime::getLocalTime();
+00410 
+00411                                                 // if not connected, try to connect ClientWithAddr
+00412                                                 if ((*itbm).second.Type == CBaseStruct::ClientWithAddr && (*itbm).second.AutoRetry)
+00413                                                 {
+00414                                                         CCallbackClient *cc = dynamic_cast<CCallbackClient *>((*itbm).second.NetBase[i]);
+00415                                                         try
+00416                                                         {
+00417                                                                 nlassert ((*itbm).second.ServiceNames.size()==1);
+00418                                                                 cc->connect (CInetAddress((*itbm).second.ServiceNames[0]));
+00419 
+00420                                                                 if ((*itbm).second.ConnectionCallback != NULL)
+00421                                                                         (*itbm).second.ConnectionCallback ((*itbm).second.Name, cc->getSockId(), (*itbm).second.ConnectionCbArg);
+00422                                                         }
+00423                                                         catch (ESocketConnectionFailed &e)
+00424                                                         {
+00425                                                                 // can't connect now, try later
+00426                                                                 nlinfo("HNETL4: can't connect now to %s (reason: %s)", (*itbm).second.ServiceNames[0].c_str(), e.what());
+00427                                                         }
+00428                                                 }
+00429                                         }
+00430                                 }       
+00431                         }
+00432                 }
+00433 
+00434                 // If it's the end, don't nlSleep()
+00435                 if (CTime::getLocalTime() - t0 > timeout)
+00436                         break;
+00437                 
+00438                 // Enable windows multithreading before rescanning all connections
+00439                 // slow down the layer H_BEFORE (CNetManager_update_nlSleep);
+00440                 nlSleep (1);
+00441                 // slow down the layer H_AFTER (CNetManager_update_nlSleep);
+00442         }
+00443 
+00444 //      sint64 p3 = CTime::getPerformanceTime ();
+00445 
+00446         if (CNamingClient::connected ())
+00447                 CNamingClient::update ();
+00448 
+00449 //      sint64 p4 = CTime::getPerformanceTime ();
+00450 
+00451 //      nlinfo("time : %f %f %f %d", CTime::ticksToSecond(p2-p1), CTime::ticksToSecond(p3-p2), CTime::ticksToSecond(p4-p3), timeout);
+00452 }
+00453 
+00454 
+00455 void CNetManager::send (const std::string &serviceName, const CMessage &buffer, TSockId hostid)
+00456 {
+00457         nldebug ("HNETL4: send for service '%s' message %s to %s", serviceName.c_str(), buffer.toString().c_str(), hostid->asString().c_str());
+00458         ItBaseMap itbm = find (serviceName);
+00459         for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00460         {
+00461                 if ((*itbm).second.NetBase[i]->connected())
+00462                         (*itbm).second.NetBase[i]->send (buffer, hostid);
+00463         }
+00464 }
+00465 
+00466 CCallbackNetBase *CNetManager::getNetBase (const std::string &serviceName)
+00467 {
+00468         ItBaseMap itbm = find (serviceName);
+00469         return (*itbm).second.NetBase[0];
+00470 }
+00471 
+00472 void CNetManager::setConnectionCallback (const std::string &serviceName, TNetManagerCallback cb, void *arg)
+00473 {
+00474         nldebug ("HNETL4: setConnectionCallback() for service '%s'", serviceName.c_str ());
+00475         ItBaseMap itbm = find (serviceName);
+00476         (*itbm).second.ConnectionCallback = cb;
+00477         (*itbm).second.ConnectionCbArg = arg;
+00478 }
+00479 
+00480 void CNetManager::setDisconnectionCallback (const std::string &serviceName, TNetManagerCallback cb, void *arg)
+00481 {
+00482         nldebug ("HNETL4: setDisconnectionCallback() for service '%s'", serviceName.c_str ());
+00483         ItBaseMap itbm = find (serviceName);
+00484         (*itbm).second.DisconnectionCallback = cb;
+00485         (*itbm).second.DisconnectionCbArg = arg;
+00486 }
+00487 
+00488 
+00489 CNetManager::ItBaseMap CNetManager::find (const std::string &serviceName)
+00490 {
+00491         // find the service or add it if not found
+00492         pair<ItBaseMap, bool> p;
+00493         p = _BaseMap.insert (make_pair (serviceName, CBaseStruct (serviceName)));
+00494         return p.first;
+00495 }
+00496 
+00497 uint64 CNetManager::getBytesSent ()
+00498 {
+00499         uint64 sent = 0;
+00500         for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00501         {
+00502                 for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00503                 {
+00504                         sent += (*itbm).second.NetBase[i]->getBytesSent ();
+00505                 }
+00506         }
+00507         return sent;
+00508 }
+00509 
+00510 uint64 CNetManager::getBytesReceived ()
+00511 {
+00512         uint64 received = 0;
+00513         for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00514         {
+00515                 for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00516                 {
+00517                         received += (*itbm).second.NetBase[i]->getBytesReceived ();
+00518                 }
+00519         }
+00520         return received;
+00521 }
+00522 
+00523 uint64 CNetManager::getSendQueueSize ()
+00524 {
+00525         uint64 val = 0;
+00526         for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00527         {
+00528                 for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00529                 {
+00530                         val += (*itbm).second.NetBase[i]->getSendQueueSize ();
+00531                 }
+00532         }
+00533         return val;
+00534 }
+00535 
+00536 uint64 CNetManager::getReceiveQueueSize ()
+00537 {
+00538         uint64 val = 0;
+00539         for (ItBaseMap itbm = _BaseMap.begin (); itbm != _BaseMap.end (); itbm++)
+00540         {
+00541                 for (uint32 i = 0; i < (*itbm).second.NetBase.size(); i++)
+00542                 {
+00543                         val += (*itbm).second.NetBase[i]->getReceiveQueueSize ();
+00544                 }
+00545         }
+00546         return val;
+00547 }
+00548 
+00549 } // NLNET
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1