00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdnet.h"
00027
00028 #include "nel/net/callback_net_base.h"
00029 #include "nel/net/callback_client.h"
00030
00031 #ifdef USE_MESSAGE_RECORDER
00032 #include "nel/net/message_recorder.h"
00033 #endif
00034
00035
00036 namespace NLNET {
00037
00038
00039
00040
00041
00042
00043 static void cbcMessageRecvAllAssociations (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
00044 {
00045 netbase.getSIDA().ignoreAllUnknownId (false);
00046 cbnbMessageRecvAssociations (msgin, from, netbase);
00047 }
00048
00049
00050 static TCallbackItem ClientMessageAssociationArray[] =
00051 {
00052 { "RAA", cbcMessageRecvAllAssociations },
00053 };
00054
00055
00056
00057
00058
00059 CCallbackClient::CCallbackClient( TRecordingState rec, const std::string& recfilename, bool recordall ) :
00060 CCallbackNetBase( rec, recfilename, recordall ), CBufClient( true, rec==Replay ), SendNextValue(0), ReceiveNextValue(0)
00061 {
00062 CBufClient::setDisconnectionCallback (_NewDisconnectionCallback, this);
00063
00064
00065 addCallbackArray (ClientMessageAssociationArray, sizeof (ClientMessageAssociationArray) / sizeof (ClientMessageAssociationArray[0]));
00066
00067 _InputSIDA.ignoreAllUnknownId (true);
00068
00069 _IsAServer = false;
00070 _DefaultCallback = NULL;
00071 }
00072
00073
00074
00075
00076
00077
00078
00079 void CCallbackClient::send (const CMessage &buffer, TSockId hostid, bool log)
00080 {
00081 nlassert (hostid == InvalidSockId);
00082 checkThreadId ();
00083 nlassert (connected ());
00084 nlassert (buffer.length() != 0);
00085 nlassert (buffer.typeIsSet());
00086
00087 _BytesSent += buffer.length ();
00088
00089
00090 {
00092
00093 }
00094
00095
00096
00097
00098 uint32 *val = (uint32*)buffer.buffer ();
00099 #ifdef NL_BIG_ENDIAN
00100 *val = NLMISC_BSWAP32(SendNextValue);
00101 #else
00102 *val = SendNextValue;
00103 #endif
00104 SendNextValue++;
00105
00106
00107 #ifdef USE_MESSAGE_RECORDER
00108 if ( _MR_RecordingState != Replay )
00109 {
00110 #endif
00111
00112
00113 CBufClient::send (buffer);
00114
00115 #ifdef USE_MESSAGE_RECORDER
00116 if ( _MR_RecordingState == Record )
00117 {
00118
00119 _MR_Recorder.recordNext( _MR_UpdateCounter, Sending, hostid, const_cast<CMessage&>(buffer) );
00120 }
00121 }
00122 else
00123 {
00125 }
00126 #endif
00127 }
00128
00129
00130
00131
00132
00133
00134 bool CCallbackClient::flush (TSockId hostid)
00135 {
00136 nlassert (hostid == InvalidSockId);
00137 checkThreadId ();
00138
00139 #ifdef USE_MESSAGE_RECORDER
00140 if ( _MR_RecordingState != Replay )
00141 {
00142 #endif
00143
00144
00145 return CBufClient::flush();
00146
00147 #ifdef USE_MESSAGE_RECORDER
00148 }
00149 else
00150 {
00151 return true;
00152 }
00153 #endif
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 void CCallbackClient::update ( sint32 timeout )
00163 {
00164
00165
00166 checkThreadId ();
00167
00168 baseUpdate (timeout);
00169
00170 #ifdef USE_MESSAGE_RECORDER
00171 if ( _MR_RecordingState != Replay )
00172 {
00173 #endif
00174
00175
00176 CBufClient::update ();
00177
00178 #ifdef USE_MESSAGE_RECORDER
00179 }
00180 #endif
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 bool CCallbackClient::dataAvailable ()
00190 {
00191 checkThreadId ();
00192
00193 #ifdef USE_MESSAGE_RECORDER
00194 if ( _MR_RecordingState != Replay )
00195 {
00196 #endif
00197
00198
00199 return CBufClient::dataAvailable ();
00200
00201 #ifdef USE_MESSAGE_RECORDER
00202 }
00203 else
00204 {
00205
00206 return CCallbackNetBase::replayDataAvailable();
00207 }
00208 #endif
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 void CCallbackClient::receive (CMessage &buffer, TSockId *hostid)
00218 {
00219 checkThreadId ();
00220 nlassert (connected ());
00221 *hostid = InvalidSockId;
00222
00223 #ifdef USE_MESSAGE_RECORDER
00224 if ( _MR_RecordingState != Replay )
00225 {
00226 #endif
00227
00228
00229 CBufClient::receive (buffer);
00230
00231
00232
00233 #ifdef NL_BIG_ENDIAN
00234 uint32 val = NLMISC_BSWAP32(*(uint32*)buffer.buffer ());
00235 #else
00236 uint32 val = *(uint32*)buffer.buffer ();
00237 #endif
00238
00239
00240 if (ReceiveNextValue != val)
00241 {
00242 nlstopex (("LNETL1: !!!LOST A MESSAGE!!! I received the message number %u but I'm waiting the message number %u (cnx %s), warn lecroart@nevrax.com with the log now please", val, ReceiveNextValue, id()->asString().c_str()));
00243
00244 ReceiveNextValue = val;
00245 }
00246 ReceiveNextValue++;
00247
00248 #ifdef USE_MESSAGE_RECORDER
00249 if ( _MR_RecordingState == Record )
00250 {
00251
00252 _MR_Recorder.recordNext( _MR_UpdateCounter, Receiving, *hostid, const_cast<CMessage&>(buffer) );
00253 }
00254 }
00255 else
00256 {
00257
00258 buffer = _MR_Recorder.ReceivedMessages.front().Message;
00259 _MR_Recorder.ReceivedMessages.pop();
00260 }
00261 #endif
00262
00263 buffer.readType ();
00264 }
00265
00266
00267
00268
00269 TSockId CCallbackClient::getSockId (TSockId hostid)
00270 {
00271 nlassert (hostid == InvalidSockId);
00272 checkThreadId ();
00273
00274 return id ();
00275 }
00276
00277
00278
00279
00280
00281
00282
00283 void CCallbackClient::connect( const CInetAddress& addr )
00284 {
00285 checkThreadId ();
00286
00287 SendNextValue = ReceiveNextValue = 0;
00288
00289 #ifdef USE_MESSAGE_RECORDER
00290 if ( _MR_RecordingState != Replay )
00291 {
00292 try
00293 {
00294 #endif
00295
00296
00297 CBufClient::connect( addr );
00298
00299 #ifdef USE_MESSAGE_RECORDER
00300 if ( _MR_RecordingState == Record )
00301 {
00302
00303 CMessage addrmsg;
00304 addrmsg.serial( const_cast<CInetAddress&>(addr) );
00305 _MR_Recorder.recordNext( _MR_UpdateCounter, Connecting, _BufSock, addrmsg );
00306 }
00307 }
00308 catch ( ESocketConnectionFailed& )
00309 {
00310 if ( _MR_RecordingState == Record )
00311 {
00312
00313 CMessage addrmsg;
00314 addrmsg.serial( const_cast<CInetAddress&>(addr) );
00315 _MR_Recorder.recordNext( _MR_UpdateCounter, ConnFailing, _BufSock, addrmsg );
00316 }
00317 throw;
00318 }
00319 }
00320 else
00321 {
00322
00323 TNetworkEvent event = _MR_Recorder.replayConnectionAttempt( addr );
00324 switch ( event )
00325 {
00326 case Connecting :
00327
00328 nlassert( ! _BufSock->Sock->connected() );
00329 _BufSock->connect( addr, _NoDelay, true );
00330 _PrevBytesDownloaded = 0;
00331 _PrevBytesUploaded = 0;
00332
00333
00334 break;
00335 case ConnFailing :
00336 throw ESocketConnectionFailed( addr );
00337
00338 default :
00339 nlwarning( "LNETL3C: No connection event in replay data, at update #%"NL_I64"u", _MR_UpdateCounter );
00340 }
00341 }
00342 #endif
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 void CCallbackClient::disconnect( TSockId hostid )
00352 {
00353 nlassert (hostid == InvalidSockId);
00354 checkThreadId ();
00355
00356 SendNextValue = ReceiveNextValue = 0;
00357
00358
00359 if ( _BufSock->connectedState() )
00360 {
00361
00362 #ifdef USE_MESSAGE_RECORDER
00363 if ( _MR_RecordingState != Replay )
00364 {
00365 #endif
00366
00367
00368 CBufClient::disconnect ();
00369
00370 #ifdef USE_MESSAGE_RECORDER
00371 }
00372 else
00373 {
00374
00375 if ( ! (_MR_Recorder.checkNextOne( _MR_UpdateCounter ) == Disconnecting) )
00376 {
00377 nlwarning( "LNETL3C: No disconnection event in the replay data, at update #%"NL_I64"u", _MR_UpdateCounter );
00378 }
00379 }
00380
00381 noticeDisconnection( _BufSock );
00382 #endif
00383 }
00384 }
00385
00386
00387 #ifdef USE_MESSAGE_RECORDER
00388
00389
00390
00391
00392
00393 bool CCallbackClient::replaySystemCallbacks()
00394 {
00395 do
00396 {
00397 if ( _MR_Recorder.ReceivedMessages.empty() )
00398 {
00399 return false;
00400 }
00401 else
00402 {
00403 switch( _MR_Recorder.ReceivedMessages.front().Event )
00404 {
00405 case Receiving:
00406 return true;
00407
00408 case Disconnecting:
00409 nldebug( "Disconnection event" );
00410 _BufSock->setConnectedState( false );
00411
00412
00413 if ( disconnectionCallback() != NULL )
00414 {
00415 disconnectionCallback()( id(), argOfDisconnectionCallback() );
00416 }
00417 break;
00418
00419 default:
00420 nlerror( "LNETL1: Invalid system event type in client receive queue" );
00421 }
00422
00423 _MR_Recorder.ReceivedMessages.pop();
00424 }
00425 }
00426 while ( true );
00427 }
00428
00429
00430 #endif // USE_MESSAGE_RECORDER
00431
00432
00433 }