internal void HandlePackage(Package message, PlayerNetworkSession playerSession) { if (message == null) { return; } if (message.Reliability == Reliability.ReliableOrdered) { if (ForceOrderingForAll == false && (playerSession.CryptoContext == null || playerSession.CryptoContext.UseEncryption == false)) { playerSession.AddToProcessing(message); } else { FastThreadPool.QueueUserWorkItem(() => playerSession.AddToProcessing(message)); } return; } playerSession.HandlePackage(message, playerSession); }
private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) { return; } Nak nak = Nak.CreateObject(); nak.Reset(); nak.Decode(receiveBytes); var queue = session.WaitingForAcksQueue; foreach (Tuple <int, int> range in nak.ranges) { Interlocked.Increment(ref ServerInfo.NumberOfNakReceive); int start = range.Item1; int end = range.Item2; for (int i = start; i <= end; i++) { session.ErrorCount++; // HACK: Just to make sure we aren't getting unessecary load on the queue during heavy buffering. //if (ServerInfo.AvailableBytes > 1000) continue; Datagram datagram; //if (queue.TryRemove(i, out datagram)) if (!session.Evicted && queue.TryRemove(i, out datagram)) { // RTT = RTT * 0.875 + rtt * 0.125 // RTTVar = RTTVar * 0.875 + abs(RTT - rtt)) * 0.125 // RTO = RTT + 4 * RTTVar long rtt = datagram.Timer.ElapsedMilliseconds; long RTT = session.Rtt; long RTTVar = session.RttVar; session.Rtt = (long)(RTT * 0.875 + rtt * 0.125); session.RttVar = (long)(RTTVar * 0.875 + Math.Abs(RTT - rtt) * 0.125); session.Rto = session.Rtt + 4 * session.RttVar + 100; // SYNC time in the end FastThreadPool.QueueUserWorkItem(delegate { var dgram = (Datagram)datagram; if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, resent datagram #{0} for {1}", dgram.Header.datagramSequenceNumber, session.Username); } SendDatagram(session, dgram); Interlocked.Increment(ref ServerInfo.NumberOfResends); }); } else { if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, no datagram #{0} for {1}", i, session.Username); } } } } nak.PutPool(); }