private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) return; Player player = session.Player; if (player == null) return; Nak nak = Nak.CreateObject(); nak.Reset(); nak.Decode(receiveBytes); var queue = session.WaitingForAcksQueue; foreach (Tuple<int, int> range in nak.ranges) { 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.TryGetValue(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 = player.Rtt; long RTTVar = player.RttVar; player.Rtt = (long) (RTT*0.875 + rtt*0.125); player.RttVar = (long) (RTTVar*0.875 + Math.Abs(RTT - rtt)*0.125); player.Rto = player.Rtt + 4*player.RttVar + 100; // SYNC time in the end //if (Log.IsDebugEnabled) // Log.ErrorFormat("NAK, resending datagram #{0} for {1}, MTU: {2}", i, player.Username, session.Mtuize); //SendDatagram(session, datagram, false); } else { if (Log.IsDebugEnabled) //Log.WarnFormat("NAK, no datagram #{0} to resend for {1}", i, player.Username); } } } nak.PutPool(); }
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++) { if (queue.TryGetValue(i, out var datagram)) { CalculateRto(session, datagram); datagram.RetransmitImmediate = true; } else { if (Log.IsDebugEnabled) { Log.WarnFormat("NAK, no datagram #{0} for {1}", i, session.Username); } } } } nak.PutPool(); }
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(); }