private void HandleNak(PlayerNetworkSession session, byte[] receiveBytes) { if (session == null) { return; } Player player = session.Player; if (player == null) { return; } Nak nak = Nak.CreateObject(); nak.Decode(receiveBytes); int ackSeqNo = nak.sequenceNumber.IntValue(); int toAckSeqNo = nak.toSequenceNumber.IntValue(); if (nak.onlyOneSequence == 1) { toAckSeqNo = ackSeqNo; } nak.PutPool(); var queue = session.WaitingForAcksQueue; Log.DebugFormat("NAK from Player {0} ({5}) #{1}-{2} IsOnlyOne {3} Count={4}", player.Username, ackSeqNo, toAckSeqNo, nak.onlyOneSequence, nak.count, player.Rtt); for (int i = ackSeqNo; i <= toAckSeqNo; i++) { session.ErrorCount++; Datagram datagram; if (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 = 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 + 10; // SYNC time in the end SendDatagram(session, datagram); } else { Log.DebugFormat("NAK, no datagram #{0} to resend for {1}", i, player.Username); } } }
private void HandleNak(byte[] receiveBytes, IPEndPoint senderEndpoint) { PlayerNetworkSession session; if (!_playerSessions.TryGetValue(senderEndpoint, out session)) { return; } Nak nak = Nak.CreateObject(); nak.Decode(receiveBytes); int ackSeqNo = nak.sequenceNumber.IntValue(); int toAckSeqNo = nak.toSequenceNumber.IntValue(); if (nak.onlyOneSequence == 1) { toAckSeqNo = ackSeqNo; } nak.PutPool(); var queue = session.WaitingForAcksQueue; Log.WarnFormat("NAK from Player {0} ({5}) #{1}-{2} IsOnlyOne {3} Count={4}", session.Player.Username, ackSeqNo, toAckSeqNo, nak.onlyOneSequence, nak.count, session.Player.Rtt); for (int i = ackSeqNo; i <= toAckSeqNo; i++) { session.ErrorCount++; Datagram datagram; if (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; if (rtt > session.Player.Rto) { Log.WarnFormat("RTT bigger !!!!!!"); } long RTT = session.Player.Rtt; long RTTVar = session.Player.RttVar; session.Player.Rtt = (long)(RTT * 0.875 + rtt * 0.125); session.Player.RttVar = (long)(RTTVar * 0.875 + Math.Abs(RTT - rtt) * 0.125); session.Player.Rto = session.Player.Rtt + 4 * session.Player.RttVar + 10; // SYNC time in the end ThreadPool.QueueUserWorkItem(delegate(object data) { SendDatagram(senderEndpoint, (Datagram)data); }, datagram); } else { Log.WarnFormat("No datagram #{0} to resend for {1}", i, session.Player.Username); } } }
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(); }