From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/callback__net__base_8cpp-source.html | 613 +++++++++++++++++++++ 1 file changed, 613 insertions(+) create mode 100644 docs/doxygen/nel/callback__net__base_8cpp-source.html (limited to 'docs/doxygen/nel/callback__net__base_8cpp-source.html') diff --git a/docs/doxygen/nel/callback__net__base_8cpp-source.html b/docs/doxygen/nel/callback__net__base_8cpp-source.html new file mode 100644 index 00000000..c3cad1fa --- /dev/null +++ b/docs/doxygen/nel/callback__net__base_8cpp-source.html @@ -0,0 +1,613 @@ + + + + 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  
+

callback_net_base.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 #include "stdnet.h"
+00027 
+00028 #include "nel/misc/string_id_array.h"
+00029 #include "nel/misc/hierarchical_timer.h"
+00030 
+00031 #include "nel/net/buf_sock.h"
+00032 #include "nel/net/callback_net_base.h"
+00033 
+00034 #ifdef USE_MESSAGE_RECORDER
+00035 #ifdef NL_OS_WINDOWS
+00036 #pragma message ( "NeL Net layer 3: message recorder enabled" )
+00037 #endif // NL_OS_WINDOWS
+00038 #include "nel/net/message_recorder.h"
+00039 #else
+00040 #ifdef NL_OS_WINDOWS
+00041 #pragma message ( "NeL Net layer 3: message recorder disabled" )
+00042 #endif // NL_OS_WINDOWS
+00043 #endif
+00044 
+00045 
+00046 using namespace std;
+00047 using namespace NLMISC;
+00048 
+00049 namespace NLNET {
+00050 
+00051 
+00052 /*
+00053  *
+00054  */
+00055 void cbnbMessageRecvAssociations (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+00056 {
+00057         // receive a new message association
+00058 
+00059         CStringIdArray::TStringId size;
+00060         msgin.serial (size);
+00061 
+00062         nldebug ("LNETL3NB_ASSOC: The other side gave me %d association strings", size);
+00063 
+00064         for (CStringIdArray::TStringId i = 0; i < size; i++)
+00065         {
+00066                 std::string name;
+00067                 CStringIdArray::TStringId id;
+00068 
+00069                 msgin.serial (name);
+00070                 msgin.serial (id);
+00071 
+00072                 // if id == -1, it means that there are no callback associated to this message
+00073                 // it should not happen, it mean that one side send a message that the other side
+00074                 // can't manage in his callbackarray.
+00075                 // to resolve the problem, add the callback in the callbackarray in the other side
+00076                 // and put NULL if you don't want to manage this message
+00077                 nlassert (id != -1);
+00078 
+00079                 nldebug ("LNETL3NB_ASSOC:  association '%s' -> %d", name.c_str (), id);
+00080                 netbase.getSIDA().addString (name, id);
+00081         }
+00082 }
+00083 
+00084 
+00085 /*
+00086  * the other side want to know some of my association, send them!
+00087  */
+00088 void cbnbMessageAskAssociations (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
+00089 {
+00090         CMessage msgout (netbase.getSIDA(), "RA");
+00091         CStringIdArray::TStringId size;
+00092         msgin.serial (size);
+00093 
+00094         nldebug ("LNETL3NB_ASSOC: The other side want %d string associations", size);
+00095 
+00096         msgout.serial (size);
+00097 
+00098         for (sint i = 0; i < size; i++)
+00099         {
+00100                 string name;
+00101                 msgin.serial (name);
+00102                 nldebug ("LNETL3NB_ASSOC:  sending association '%s' -> %d", name.c_str (), netbase._OutputSIDA.getId(name));
+00103 
+00104                 // if this assert occurs, it means that the other side ask an unknown message
+00105                 // or that there are different types of client (with differents callbackarray) and one of the client doesn't have this callback
+00106                 nlassert(netbase._OutputSIDA.getId(name) != -1);
+00107 
+00108                 msgout.serial (name);
+00109 
+00110                 CStringIdArray::TStringId id = netbase._OutputSIDA.getId (name);
+00111                 msgout.serial (id);
+00112         }
+00113         // send the message to the other side
+00114         netbase.send (msgout, from);
+00115 }
+00116 
+00117 static TCallbackItem cbnbMessageAssociationArray[] =
+00118 {
+00119         { "AA", cbnbMessageAskAssociations },
+00120         { "RA", cbnbMessageRecvAssociations },
+00121 };
+00122 
+00123 
+00124 /*
+00125  * Disconnection callback
+00126  */
+00127 void cbnbNewDisconnection (TSockId from, void *data)
+00128 {
+00129         nlassert (data != NULL);
+00130         CCallbackNetBase *base = (CCallbackNetBase *)data;
+00131 
+00132         nldebug("LNETL3NB: cbnbNewDisconnection()");
+00133 
+00134 #ifdef USE_MESSAGE_RECORDER
+00135         // Record or replay disconnection
+00136         base->noticeDisconnection( from );
+00137 #endif
+00138         
+00139         // Call the client callback if necessary
+00140         if (base->_DisconnectionCallback != NULL)
+00141                 base->_DisconnectionCallback (from, base->_DisconnectionCbArg);
+00142 }
+00143 
+00144 
+00145 /*
+00146  * Constructor
+00147  */
+00148 CCallbackNetBase::CCallbackNetBase(  TRecordingState rec, const string& recfilename, bool recordall ) :
+00149         _FirstUpdate (true), _DisconnectionCallback(NULL), _DisconnectionCbArg(NULL)
+00150 #ifdef USE_MESSAGE_RECORDER
+00151         , _MR_RecordingState(rec), _MR_UpdateCounter(0)
+00152 #endif
+00153 {
+00154         _ThreadId = getThreadId ();
+00155         _NewDisconnectionCallback = cbnbNewDisconnection;
+00156 
+00157         _BytesSent = 0;
+00158         _BytesReceived = 0;
+00159 
+00160         createDebug(); // for addNegativeFilter to work even in release and releasedebug modes
+00161 
+00162         // add the callback needed to associate messages with id
+00163         addCallbackArray (cbnbMessageAssociationArray, sizeof (cbnbMessageAssociationArray) / sizeof (cbnbMessageAssociationArray[0]));
+00164 
+00165 #ifdef USE_MESSAGE_RECORDER
+00166         switch ( _MR_RecordingState )
+00167         {
+00168         case Record :
+00169                 _MR_Recorder.startRecord( recfilename, recordall );
+00170                 break;
+00171         case Replay :
+00172                 _MR_Recorder.startReplay( recfilename );
+00173                 break;
+00174         default:;
+00175                 // No recording
+00176         }
+00177 #endif
+00178 }
+00179 
+00180 
+00181 /*
+00182  *      Append callback array with the specified array
+00183  */
+00184 void CCallbackNetBase::addCallbackArray (const TCallbackItem *callbackarray, CStringIdArray::TStringId arraysize)
+00185 {
+00186         checkThreadId ();
+00187 
+00188         // be sure that the 2 array have the same size
+00189         nlassert (_CallbackArray.size () == (uint)_OutputSIDA.size ());
+00190 
+00191         if (arraysize == 1 && callbackarray[0].Callback == NULL && string("") == callbackarray[0].Key)
+00192         {
+00193                 // it's an empty array, ignore it
+00194                 return;
+00195         }
+00196 
+00197         // resize the array
+00198         sint oldsize = _CallbackArray.size();
+00199 
+00200         _CallbackArray.resize (oldsize + arraysize);
+00201         _OutputSIDA.resize (oldsize + arraysize);
+00202 
+00203 //TOO MUCH MESSAGE      nldebug ("L3NB_CB: Adding %d callback to the array", arraysize);
+00204 
+00205         for (sint i = 0; i < arraysize; i++)
+00206         {
+00207                 CStringIdArray::TStringId ni = oldsize + i;
+00208 //TOO MUCH MESSAGE              nldebug ("L3NB_CB: Adding callback to message '%s', id '%d'", callbackarray[i].Key, ni);
+00209                 // copy callback value
+00210                 
+00211                 _CallbackArray[ni] = callbackarray[i];
+00212                 // add the string to the string id array
+00213                 _OutputSIDA.addString (callbackarray[i].Key, ni);
+00214 
+00215         }
+00216 //      nldebug ("LNETL3NB_CB: Added %d callback Now, there's %d callback associated with message type", arraysize, _CallbackArray.size ());
+00217 }
+00218 
+00219 
+00220 /*
+00221  * processOneMessage()
+00222  */
+00223 void CCallbackNetBase::processOneMessage ()
+00224 {
+00225         checkThreadId ();
+00226 
+00227         // slow down the layer H_AUTO (CCallbackNetBase_processOneMessage);
+00228 
+00229         CMessage msgin (_OutputSIDA, "", true);
+00230         TSockId tsid;
+00231         receive (msgin, &tsid);
+00232 
+00233         _BytesReceived += msgin.length ();
+00234         
+00235         // now, we have to call the good callback
+00236         NLMISC::CStringIdArray::TStringId pos = -1;
+00237         if (msgin.TypeHasAnId)
+00238         {
+00239                 pos = msgin.getId ();
+00240         }
+00241         else
+00242         {
+00243                 std::string name = msgin.getName ();
+00244                 sint16 i;
+00245                 for (i = 0; i < (sint16) _CallbackArray.size (); i++)
+00246                 {
+00247                         if (name == _CallbackArray[i].Key)
+00248                         {
+00249                                 pos = i;
+00250                                 break;
+00251                         }
+00252                 }
+00253         }
+00254 
+00255         TMsgCallback    cb = NULL;
+00256         if (pos < 0 || pos >= (sint16) _CallbackArray.size ())
+00257         {
+00258                 if (_DefaultCallback == NULL)
+00259                 {
+00260                         nlwarning ("LNETL3NB_CB: Callback %s not found in _CallbackArray", msgin.toString().c_str());
+00261                 }
+00262                 else
+00263                 {
+00264                         cb = _DefaultCallback;
+00265                 }
+00266         }
+00267         else
+00268         {
+00269                 cb = _CallbackArray[pos].Callback;
+00270         }
+00271 
+00272         TSockId realid = getSockId (tsid);
+00273 
+00274         if (!realid->AuthorizedCallback.empty() && msgin.getName() != realid->AuthorizedCallback)
+00275         {
+00276                 nlwarning ("LNETL3NB_CB: %s try to call the callback %s but only %s is authorized. Disconnect him!", tsid->asString().c_str(), msgin.toString().c_str(), tsid->AuthorizedCallback.c_str());
+00277                 disconnect (tsid);
+00278         }
+00279         else if (cb == NULL)
+00280         {
+00281                 nlwarning ("LNETL3NB_CB: Callback %s is NULL, can't call it", msgin.toString().c_str());
+00282         }
+00283         else
+00284         {
+00285                 nldebug ("LNETL3NB_CB: Calling callback (%s)%s", msgin.getName().c_str(), (cb==_DefaultCallback)?" DEFAULT_CB":"");
+00286                 cb(msgin, realid, *this);
+00287         }
+00288         
+00289 /*
+00290         if (pos < 0 || pos >= (sint16) _CallbackArray.size ())
+00291         {
+00292                 if (_DefaultCallback == NULL)
+00293                         nlwarning ("LNETL3NB_CB: Callback %s not found in _CallbackArray", msgin.toString().c_str());
+00294                 else
+00295                 {
+00296                         // ...
+00297                 }
+00298         }
+00299         else
+00300         {
+00301                 TSockId realid = getSockId (tsid);
+00302 
+00303                 if (!realid->AuthorizedCallback.empty() && msgin.getName() != realid->AuthorizedCallback)
+00304                 {
+00305                         nlwarning ("LNETL3NB_CB: %s try to call the callback %s but only %s is authorized. Disconnect him!", tsid->asString().c_str(), msgin.toString().c_str(), tsid->AuthorizedCallback.c_str());
+00306                         disconnect (tsid);
+00307                 }
+00308                 else if (_CallbackArray[pos].Callback == NULL)
+00309                 {
+00310                         nlwarning ("LNETL3NB_CB: Callback %s is NULL, can't call it", msgin.toString().c_str());
+00311                 }
+00312                 else
+00313                 {
+00314                         nldebug ("LNETL3NB_CB: Calling callback (%s)", _CallbackArray[pos].Key);
+00315                         _CallbackArray[pos].Callback (msgin, realid, *this);
+00316                 }
+00317         }
+00318 */
+00319 }
+00320 
+00321 
+00322 
+00323 /*
+00324  * baseUpdate
+00325  * Recorded : YES
+00326  * Replayed : YES
+00327  */
+00328 void CCallbackNetBase::baseUpdate (sint32 timeout)
+00329 {
+00330         checkThreadId ();
+00331 
+00332         // slow down the layer H_AUTO (CCallbackNetBase_baseUpdate);
+00333 
+00334         nlassert( timeout >= -1 );
+00335         TTime t0 = CTime::getLocalTime();
+00336 
+00337         //
+00338         // The first time, we init time counters
+00339         //
+00340         if (_FirstUpdate)
+00341         {
+00342 //              nldebug("LNETL3NB: First update()");
+00343                 _FirstUpdate = false;
+00344                 _LastUpdateTime = t0;
+00345                 _LastMovedStringArray = t0;
+00346         }
+00347 
+00348         //
+00349         // Every 1 seconds if we have new unknown association, we ask them to the other side
+00350         //
+00351         if (t0 - _LastUpdateTime >  1000)
+00352         {
+00353 //              nldebug("LNETL3NB: baseUpdate()");
+00354                 _LastUpdateTime = t0;
+00355 
+00356                 const set<string> &sa = _InputSIDA.getNeedToAskedStringArray ();
+00357                 if (!sa.empty ())
+00358                 {
+00359                         CMessage msgout (_InputSIDA, "AA");
+00360                         //nlassert (sa.size () < 65536); // no size limit anymore
+00361                         CStringIdArray::TStringId size = sa.size ();
+00362                         nldebug ("LNETL3NB_ASSOC: I need %d string association, ask them to the other side", size);
+00363                         msgout.serial (size);
+00364                         for (set<string>::iterator it = sa.begin(); it != sa.end(); it++)
+00365                         {
+00366                                 nldebug ("LNETL3NB_ASSOC:  what is the id of '%s'?", (*it).c_str ());
+00367                                 string str(*it);
+00368                                 msgout.serial (str);
+00369                         }
+00370                         // send the message to the other side
+00371                         send (msgout, 0);
+00372                         _InputSIDA.moveNeedToAskToAskedStringArray();
+00373                         _LastMovedStringArray = t0;
+00374                 }
+00375         }
+00376 
+00377         //
+00378         // Every 60 seconds if we have not answered association, we ask again to get them!
+00379         //
+00380         if (!_InputSIDA.getAskedStringArray().empty() && t0 - _LastMovedStringArray > 60000)
+00381         {
+00382                 // we didn't have an answer for the association, resend them
+00383                 const set<string> sa = _InputSIDA.getAskedStringArray ();
+00384                 CMessage msgout (_InputSIDA, "AA");
+00385                 //nlassert (sa.size () < 65536); // no size limit anymore
+00386                 CStringIdArray::TStringId size = sa.size ();
+00387                 nldebug ("LNETL3NB_ASSOC: client didn't answer my asked association, retry! I need %d string association, ask them to the other side", size);
+00388                 msgout.serial (size);
+00389                 for (set<string>::iterator it = sa.begin(); it != sa.end(); it++)
+00390                 {
+00391                         nldebug ("LNETL3NB_ASSOC:  what is the id of '%s'?", (*it).c_str ());
+00392                         string str(*it);
+00393                         msgout.serial (str);
+00394                 }
+00395                 // sends the message to the other side
+00396                 send (msgout, 0);
+00397                 _LastMovedStringArray = t0;
+00398         }
+00399 
+00400         /*
+00401          * timeout -1    =>  read one message in the queue or nothing if no message in queue
+00402          * timeout 0     =>  read all messages in the queue
+00403          * timeout other =>  read all messages in the queue until timeout expired (at least all one time)
+00404          */
+00405 
+00406         bool exit = false;
+00407 
+00408         while (!exit)
+00409         {
+00410                 // process all messages in the queue
+00411                 while (dataAvailable ())
+00412                 {
+00413                         processOneMessage ();
+00414                         if (timeout == -1)
+00415                         {
+00416                                 exit = true;
+00417                                 break;
+00418                         }
+00419                 }
+00420 
+00421                 // need to exit?
+00422                 if (timeout == 0 || (sint32)(CTime::getLocalTime() - t0) > timeout)
+00423                 {
+00424                         exit = true;
+00425                 }
+00426                 else
+00427                 {
+00428                         // enable multithreading on windows :-/
+00429                         // slow down the layer H_AUTO (CCallbackNetBase_baseUpdate_nlSleep);
+00430                         nlSleep (10);
+00431                 }
+00432         }
+00433 
+00434 #ifdef USE_MESSAGE_RECORDER
+00435         _MR_UpdateCounter++;
+00436 #endif
+00437 
+00438 }
+00439 
+00440 
+00441 const   CInetAddress& CCallbackNetBase::hostAddress (TSockId hostid)
+00442 {
+00443         // should never be called
+00444         nlstop;
+00445         static CInetAddress tmp;
+00446         return tmp;
+00447 }
+00448 
+00449 void    CCallbackNetBase::setOtherSideAssociations (const char **associationarray, NLMISC::CStringIdArray::TStringId arraysize)
+00450 {
+00451         checkThreadId ();
+00452 
+00453         nldebug ("LNETL3NB_ASSOC: setOtherSideAssociations() sets %d association strings", arraysize);
+00454 
+00455         for (sint i = 0; i < arraysize; i++)
+00456         {
+00457                 nldebug ("LNETL3NB_ASSOC:  association '%s' -> %d", associationarray[i], i);
+00458                 getSIDA().addString (associationarray[i], i);
+00459         }
+00460 }
+00461 
+00462 void    CCallbackNetBase::displayAllMyAssociations ()
+00463 {
+00464         checkThreadId ();
+00465 
+00466         _OutputSIDA.display ();
+00467 }
+00468 
+00469 void    CCallbackNetBase::authorizeOnly (const char *callbackName, TSockId hostid)
+00470 {
+00471         checkThreadId ();
+00472 
+00473         nldebug ("LNETL3NB: authorizeOnly (%s, %s)", callbackName, hostid->asString().c_str());
+00474 
+00475         hostid = getSockId (hostid);
+00476         
+00477         nlassert (hostid != InvalidSockId);
+00478 
+00479         hostid->AuthorizedCallback = (callbackName == NULL)?"":callbackName;
+00480 }
+00481 
+00482 
+00483 #ifdef USE_MESSAGE_RECORDER
+00484 
+00485 /*
+00486  * Replay dataAvailable() in replay mode
+00487  */
+00488 bool CCallbackNetBase::replayDataAvailable()
+00489 {
+00490         nlassert( _MR_RecordingState == Replay );
+00491 
+00492         if ( _MR_Recorder.ReceivedMessages.empty() )
+00493         {
+00494                 // Fill the queue of received messages related to the present update
+00495                 _MR_Recorder.replayNextDataAvailable( _MR_UpdateCounter );
+00496         }
+00497 
+00498         return replaySystemCallbacks();
+00499 }
+00500 
+00501 
+00502 /*
+00503  * Record or replay disconnection
+00504  */
+00505 void CCallbackNetBase::noticeDisconnection( TSockId hostid )
+00506 {
+00507         nlassert (hostid != InvalidSockId);     // invalid hostid
+00508         if ( _MR_RecordingState != Replay )
+00509         {
+00510                 if ( _MR_RecordingState == Record )
+00511                 {
+00512                         // Record disconnection
+00513                         CMessage emptymsg;
+00514                         _MR_Recorder.recordNext( _MR_UpdateCounter, Disconnecting, hostid, emptymsg );
+00515                 }
+00516         }
+00517         else
+00518         {
+00519                 // Replay disconnection
+00520                 hostid->disconnect( false );
+00521         }
+00522 }
+00523 
+00524 #endif // USE_MESSAGE_RECORDER
+00525 
+00526 
+00527 
+00528 /*
+00529  * checkThreadId
+00530  */
+00531 void CCallbackNetBase::checkThreadId () const
+00532 {
+00533 /*      some people use this class in different thread but with a mutex to be sure to have
+00534         no concurent access
+00535         if (getThreadId () != _ThreadId)
+00536         {
+00537                 nlerror ("You try to access to the same CCallbackClient or CCallbackServer with 2 differents thread (%d and %d)", _ThreadId, getThreadId());
+00538         }
+00539 */
+00540 }
+00541 
+00542 
+00543 } // NLNET
+00544 
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1