| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857 |
- #if DEBUG && !UNITY_WP_8_1 && !UNITY_WSA_8_1
- using System;
- using System.Collections.Generic;
- using System.Text;
- using FlyingWormConsole3.LiteNetLib.Utils;
- namespace FlyingWormConsole3.LiteNetLib
- {
- public enum ConnectionState
- {
- InProgress,
- Connected,
- Disconnected
- }
- public sealed class NetPeer
- {
- //Flow control
- private int _currentFlowMode;
- private int _sendedPacketsCount;
- private int _flowTimer;
- //Ping and RTT
- private int _ping;
- private int _rtt;
- private int _avgRtt;
- private int _rttCount;
- private int _goodRttCount;
- private ushort _pingSequence;
- private ushort _remotePingSequence;
- private double _resendDelay = 27.0;
- private int _pingSendTimer;
- private const int RttResetDelay = 1000;
- private int _rttResetTimer;
- private DateTime _pingTimeStart;
- private int _timeSinceLastPacket;
- //Common
- private readonly NetEndPoint _remoteEndPoint;
- private readonly NetManager _peerListener;
- private readonly NetPacketPool _packetPool;
- private readonly object _flushLock = new object();
- //Channels
- private readonly ReliableChannel _reliableOrderedChannel;
- private readonly ReliableChannel _reliableUnorderedChannel;
- private readonly SequencedChannel _sequencedChannel;
- private readonly SimpleChannel _simpleChannel;
- private int _windowSize = NetConstants.DefaultWindowSize;
- //MTU
- private int _mtu = NetConstants.PossibleMtu[0];
- private int _mtuIdx;
- private bool _finishMtu;
- private int _mtuCheckTimer;
- private int _mtuCheckAttempts;
- private const int MtuCheckDelay = 1000;
- private const int MaxMtuCheckAttempts = 4;
- private readonly object _mtuMutex = new object();
- //Fragment
- private class IncomingFragments
- {
- public NetPacket[] Fragments;
- public int ReceivedCount;
- public int TotalSize;
- }
- private ushort _fragmentId;
- private readonly Dictionary<ushort, IncomingFragments> _holdedFragments;
- //Merging
- private readonly NetPacket _mergeData;
- private int _mergePos;
- private int _mergeCount;
- //Connection
- private int _connectAttempts;
- private int _connectTimer;
- private long _connectId;
- private ConnectionState _connectionState;
- public ConnectionState ConnectionState
- {
- get { return _connectionState; }
- }
- public long ConnectId
- {
- get { return _connectId; }
- }
- public NetEndPoint EndPoint
- {
- get { return _remoteEndPoint; }
- }
- public int Ping
- {
- get { return _ping; }
- }
- public int CurrentFlowMode
- {
- get { return _currentFlowMode; }
- }
- public int Mtu
- {
- get { return _mtu; }
- }
- public int TimeSinceLastPacket
- {
- get { return _timeSinceLastPacket; }
- }
- public NetManager NetManager
- {
- get { return _peerListener; }
- }
- public int PacketsCountInReliableQueue
- {
- get { return _reliableUnorderedChannel.PacketsInQueue; }
- }
- public int PacketsCountInReliableOrderedQueue
- {
- get { return _reliableOrderedChannel.PacketsInQueue; }
- }
- internal double ResendDelay
- {
- get { return _resendDelay; }
- }
- /// <summary>
- /// Application defined object containing data about the connection
- /// </summary>
- public object Tag;
- internal NetPeer(NetManager peerListener, NetEndPoint remoteEndPoint, long connectId)
- {
- _packetPool = peerListener.PacketPool;
- _peerListener = peerListener;
- _remoteEndPoint = remoteEndPoint;
- _avgRtt = 0;
- _rtt = 0;
- _pingSendTimer = 0;
- _reliableOrderedChannel = new ReliableChannel(this, true, _windowSize);
- _reliableUnorderedChannel = new ReliableChannel(this, false, _windowSize);
- _sequencedChannel = new SequencedChannel(this);
- _simpleChannel = new SimpleChannel(this);
- _holdedFragments = new Dictionary<ushort, IncomingFragments>();
- _mergeData = _packetPool.Get(PacketProperty.Merged, NetConstants.MaxPacketSize);
- //if ID != 0 then we already connected
- _connectAttempts = 0;
- if (connectId == 0)
- {
- _connectId = DateTime.UtcNow.Ticks;
- SendConnectRequest();
- }
- else
- {
- _connectId = connectId;
- _connectionState = ConnectionState.Connected;
- SendConnectAccept();
- }
- NetUtils.DebugWrite(ConsoleColor.Cyan, "[CC] ConnectId: {0}", _connectId);
- }
- private void SendConnectRequest()
- {
- //Get connect key bytes
- byte[] keyData = Encoding.UTF8.GetBytes(_peerListener.ConnectKey);
- //Make initial packet
- var connectPacket = _packetPool.Get(PacketProperty.ConnectRequest, 12 + keyData.Length);
- //Add data
- FastBitConverter.GetBytes(connectPacket.RawData, 1, NetConstants.ProtocolId);
- FastBitConverter.GetBytes(connectPacket.RawData, 5, _connectId);
- Buffer.BlockCopy(keyData, 0, connectPacket.RawData, 13, keyData.Length);
- //Send raw
- _peerListener.SendRawAndRecycle(connectPacket, _remoteEndPoint);
- }
- private void SendConnectAccept()
- {
- //Reset connection timer
- _timeSinceLastPacket = 0;
- //Make initial packet
- var connectPacket = _packetPool.Get(PacketProperty.ConnectAccept, 8);
- //Add data
- FastBitConverter.GetBytes(connectPacket.RawData, 1, _connectId);
- //Send raw
- _peerListener.SendRawAndRecycle(connectPacket, _remoteEndPoint);
- }
- internal bool ProcessConnectAccept(NetPacket packet)
- {
- if (_connectionState != ConnectionState.InProgress)
- return false;
- //check connection id
- if (BitConverter.ToInt64(packet.RawData, 1) != _connectId)
- {
- return false;
- }
- NetUtils.DebugWrite(ConsoleColor.Cyan, "[NC] Received connection accept");
- _timeSinceLastPacket = 0;
- _connectionState = ConnectionState.Connected;
- return true;
- }
- private static PacketProperty SendOptionsToProperty(SendOptions options)
- {
- switch (options)
- {
- case SendOptions.ReliableUnordered:
- return PacketProperty.Reliable;
- case SendOptions.Sequenced:
- return PacketProperty.Sequenced;
- case SendOptions.ReliableOrdered:
- return PacketProperty.ReliableOrdered;
- default:
- return PacketProperty.Unreliable;
- }
- }
- public int GetMaxSinglePacketSize(SendOptions options)
- {
- return _mtu - NetPacket.GetHeaderSize(SendOptionsToProperty(options));
- }
- public void Send(byte[] data, SendOptions options)
- {
- Send(data, 0, data.Length, options);
- }
- public void Send(NetDataWriter dataWriter, SendOptions options)
- {
- Send(dataWriter.Data, 0, dataWriter.Length, options);
- }
- public void Send(byte[] data, int start, int length, SendOptions options)
- {
- //Prepare
- PacketProperty property = SendOptionsToProperty(options);
- int headerSize = NetPacket.GetHeaderSize(property);
- //Check fragmentation
- if (length + headerSize > _mtu)
- {
- if (options == SendOptions.Sequenced || options == SendOptions.Unreliable)
- {
- throw new Exception("Unreliable packet size > allowed (" + (_mtu - headerSize) + ")");
- }
-
- int packetFullSize = _mtu - headerSize;
- int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize;
- int fullPacketsCount = length / packetDataSize;
- int lastPacketSize = length % packetDataSize;
- int totalPackets = fullPacketsCount + (lastPacketSize == 0 ? 0 : 1);
- NetUtils.DebugWrite("FragmentSend:\n" +
- " MTU: {0}\n" +
- " headerSize: {1}\n" +
- " packetFullSize: {2}\n" +
- " packetDataSize: {3}\n" +
- " fullPacketsCount: {4}\n" +
- " lastPacketSize: {5}\n" +
- " totalPackets: {6}",
- _mtu, headerSize, packetFullSize, packetDataSize, fullPacketsCount, lastPacketSize, totalPackets);
- if (totalPackets > ushort.MaxValue)
- {
- throw new Exception("Too many fragments: " + totalPackets + " > " + ushort.MaxValue);
- }
- int dataOffset = headerSize + NetConstants.FragmentHeaderSize;
- for (ushort i = 0; i < fullPacketsCount; i++)
- {
- NetPacket p = _packetPool.Get(property, packetFullSize);
- p.FragmentId = _fragmentId;
- p.FragmentPart = i;
- p.FragmentsTotal = (ushort)totalPackets;
- p.IsFragmented = true;
- Buffer.BlockCopy(data, i * packetDataSize, p.RawData, dataOffset, packetDataSize);
- SendPacket(p);
- }
-
- if (lastPacketSize > 0)
- {
- NetPacket p = _packetPool.Get(property, lastPacketSize + NetConstants.FragmentHeaderSize);
- p.FragmentId = _fragmentId;
- p.FragmentPart = (ushort)fullPacketsCount; //last
- p.FragmentsTotal = (ushort)totalPackets;
- p.IsFragmented = true;
- Buffer.BlockCopy(data, fullPacketsCount * packetDataSize, p.RawData, dataOffset, lastPacketSize);
- SendPacket(p);
- }
- _fragmentId++;
- return;
- }
- //Else just send
- NetPacket packet = _packetPool.GetWithData(property, data, start, length);
- SendPacket(packet);
- }
- private void CreateAndSend(PacketProperty property, ushort sequence)
- {
- NetPacket packet = _packetPool.Get(property, 0);
- packet.Sequence = sequence;
- SendPacket(packet);
- }
- //from user thread, our thread, or recv?
- private void SendPacket(NetPacket packet)
- {
- NetUtils.DebugWrite("[RS]Packet: " + packet.Property);
- switch (packet.Property)
- {
- case PacketProperty.Reliable:
- _reliableUnorderedChannel.AddToQueue(packet);
- break;
- case PacketProperty.Sequenced:
- _sequencedChannel.AddToQueue(packet);
- break;
- case PacketProperty.ReliableOrdered:
- _reliableOrderedChannel.AddToQueue(packet);
- break;
- case PacketProperty.Unreliable:
- _simpleChannel.AddToQueue(packet);
- break;
- case PacketProperty.MtuCheck:
- //Must check result for MTU fix
- if (!_peerListener.SendRawAndRecycle(packet, _remoteEndPoint))
- {
- _finishMtu = true;
- }
- break;
- case PacketProperty.AckReliable:
- case PacketProperty.AckReliableOrdered:
- case PacketProperty.Ping:
- case PacketProperty.Pong:
- case PacketProperty.Disconnect:
- case PacketProperty.MtuOk:
- SendRawData(packet);
- _packetPool.Recycle(packet);
- break;
- default:
- throw new Exception("Unknown packet property: " + packet.Property);
- }
- }
- private void UpdateRoundTripTime(int roundTripTime)
- {
- //Calc average round trip time
- _rtt += roundTripTime;
- _rttCount++;
- _avgRtt = _rtt/_rttCount;
- //flowmode 0 = fastest
- //flowmode max = lowest
- if (_avgRtt < _peerListener.GetStartRtt(_currentFlowMode - 1))
- {
- if (_currentFlowMode <= 0)
- {
- //Already maxed
- return;
- }
- _goodRttCount++;
- if (_goodRttCount > NetConstants.FlowIncreaseThreshold)
- {
- _goodRttCount = 0;
- _currentFlowMode--;
- NetUtils.DebugWrite("[PA]Increased flow speed, RTT: {0}, PPS: {1}", _avgRtt, _peerListener.GetPacketsPerSecond(_currentFlowMode));
- }
- }
- else if(_avgRtt > _peerListener.GetStartRtt(_currentFlowMode))
- {
- _goodRttCount = 0;
- if (_currentFlowMode < _peerListener.GetMaxFlowMode())
- {
- _currentFlowMode++;
- NetUtils.DebugWrite("[PA]Decreased flow speed, RTT: {0}, PPS: {1}", _avgRtt, _peerListener.GetPacketsPerSecond(_currentFlowMode));
- }
- }
- //recalc resend delay
- double avgRtt = _avgRtt;
- if (avgRtt <= 0.0)
- avgRtt = 0.1;
- _resendDelay = 25 + (avgRtt * 2.1); // 25 ms + double rtt
- }
- internal void AddIncomingPacket(NetPacket p)
- {
- if (p.IsFragmented)
- {
- NetUtils.DebugWrite("Fragment. Id: {0}, Part: {1}, Total: {2}", p.FragmentId, p.FragmentPart, p.FragmentsTotal);
- //Get needed array from dictionary
- ushort packetFragId = p.FragmentId;
- IncomingFragments incomingFragments;
- if (!_holdedFragments.TryGetValue(packetFragId, out incomingFragments))
- {
- incomingFragments = new IncomingFragments
- {
- Fragments = new NetPacket[p.FragmentsTotal]
- };
- _holdedFragments.Add(packetFragId, incomingFragments);
- }
- //Cache
- var fragments = incomingFragments.Fragments;
- //Error check
- if (p.FragmentPart >= fragments.Length || fragments[p.FragmentPart] != null)
- {
- _packetPool.Recycle(p);
- NetUtils.DebugWriteError("Invalid fragment packet");
- return;
- }
- //Fill array
- fragments[p.FragmentPart] = p;
- //Increase received fragments count
- incomingFragments.ReceivedCount++;
- //Increase total size
- int dataOffset = p.GetHeaderSize() + NetConstants.FragmentHeaderSize;
- incomingFragments.TotalSize += p.Size - dataOffset;
- //Check for finish
- if (incomingFragments.ReceivedCount != fragments.Length)
- {
- return;
- }
- NetUtils.DebugWrite("Received all fragments!");
- NetPacket resultingPacket = _packetPool.Get( p.Property, incomingFragments.TotalSize );
- int resultingPacketOffset = resultingPacket.GetHeaderSize();
- int firstFragmentSize = fragments[0].Size - dataOffset;
- for (int i = 0; i < incomingFragments.ReceivedCount; i++)
- {
- //Create resulting big packet
- int fragmentSize = fragments[i].Size - dataOffset;
- Buffer.BlockCopy(
- fragments[i].RawData,
- dataOffset,
- resultingPacket.RawData,
- resultingPacketOffset + firstFragmentSize * i,
- fragmentSize);
- //Free memory
- _packetPool.Recycle(fragments[i]);
- fragments[i] = null;
- }
- //Send to process
- _peerListener.ReceiveFromPeer(resultingPacket, _remoteEndPoint);
- //Clear memory
- _packetPool.Recycle(resultingPacket);
- _holdedFragments.Remove(packetFragId);
- }
- else //Just simple packet
- {
- _peerListener.ReceiveFromPeer(p, _remoteEndPoint);
- _packetPool.Recycle(p);
- }
- }
- private void ProcessMtuPacket(NetPacket packet)
- {
- if (packet.Size == 1 ||
- packet.RawData[1] >= NetConstants.PossibleMtu.Length)
- return;
- //MTU auto increase
- if (packet.Property == PacketProperty.MtuCheck)
- {
- if (packet.Size != NetConstants.PossibleMtu[packet.RawData[1]])
- {
- return;
- }
- _mtuCheckAttempts = 0;
- NetUtils.DebugWrite("MTU check. Resend: " + packet.RawData[1]);
- var mtuOkPacket = _packetPool.Get(PacketProperty.MtuOk, 1);
- mtuOkPacket.RawData[1] = packet.RawData[1];
- SendPacket(mtuOkPacket);
- }
- else if(packet.RawData[1] > _mtuIdx) //MtuOk
- {
- lock (_mtuMutex)
- {
- _mtuIdx = packet.RawData[1];
- _mtu = NetConstants.PossibleMtu[_mtuIdx];
- }
- //if maxed - finish.
- if (_mtuIdx == NetConstants.PossibleMtu.Length - 1)
- {
- _finishMtu = true;
- }
- NetUtils.DebugWrite("MTU ok. Increase to: " + _mtu);
- }
- }
- //Process incoming packet
- internal void ProcessPacket(NetPacket packet)
- {
- _timeSinceLastPacket = 0;
- NetUtils.DebugWrite("[RR]PacketProperty: {0}", packet.Property);
- switch (packet.Property)
- {
- case PacketProperty.ConnectRequest:
- //response with connect
- long newId = BitConverter.ToInt64(packet.RawData, 1);
- if (newId > _connectId)
- {
- _connectId = newId;
- }
- NetUtils.DebugWrite("ConnectRequest LastId: {0}, NewId: {1}, EP: {2}", ConnectId, newId, _remoteEndPoint);
- SendConnectAccept();
- _packetPool.Recycle(packet);
- break;
- case PacketProperty.Merged:
- int pos = NetConstants.HeaderSize;
- while (pos < packet.Size)
- {
- ushort size = BitConverter.ToUInt16(packet.RawData, pos);
- pos += 2;
- NetPacket mergedPacket = _packetPool.GetAndRead(packet.RawData, pos, size);
- if (mergedPacket == null)
- {
- _packetPool.Recycle(packet);
- break;
- }
- pos += size;
- ProcessPacket(mergedPacket);
- }
- break;
- //If we get ping, send pong
- case PacketProperty.Ping:
- if (NetUtils.RelativeSequenceNumber(packet.Sequence, _remotePingSequence) < 0)
- {
- _packetPool.Recycle(packet);
- break;
- }
- NetUtils.DebugWrite("[PP]Ping receive, send pong");
- _remotePingSequence = packet.Sequence;
- _packetPool.Recycle(packet);
- //send
- CreateAndSend(PacketProperty.Pong, _remotePingSequence);
- break;
- //If we get pong, calculate ping time and rtt
- case PacketProperty.Pong:
- if (NetUtils.RelativeSequenceNumber(packet.Sequence, _pingSequence) < 0)
- {
- _packetPool.Recycle(packet);
- break;
- }
- _pingSequence = packet.Sequence;
- int rtt = (int)(DateTime.UtcNow - _pingTimeStart).TotalMilliseconds;
- UpdateRoundTripTime(rtt);
- NetUtils.DebugWrite("[PP]Ping: {0}", rtt);
- _packetPool.Recycle(packet);
- break;
- //Process ack
- case PacketProperty.AckReliable:
- _reliableUnorderedChannel.ProcessAck(packet);
- _packetPool.Recycle(packet);
- break;
- case PacketProperty.AckReliableOrdered:
- _reliableOrderedChannel.ProcessAck(packet);
- _packetPool.Recycle(packet);
- break;
- //Process in order packets
- case PacketProperty.Sequenced:
- _sequencedChannel.ProcessPacket(packet);
- break;
- case PacketProperty.Reliable:
- _reliableUnorderedChannel.ProcessPacket(packet);
- break;
- case PacketProperty.ReliableOrdered:
- _reliableOrderedChannel.ProcessPacket(packet);
- break;
- //Simple packet without acks
- case PacketProperty.Unreliable:
- AddIncomingPacket(packet);
- return;
- case PacketProperty.MtuCheck:
- case PacketProperty.MtuOk:
- ProcessMtuPacket(packet);
- break;
- default:
- NetUtils.DebugWriteError("Error! Unexpected packet type: " + packet.Property);
- break;
- }
- }
- private static bool CanMerge(PacketProperty property)
- {
- switch (property)
- {
- case PacketProperty.ConnectAccept:
- case PacketProperty.ConnectRequest:
- case PacketProperty.MtuOk:
- case PacketProperty.Pong:
- case PacketProperty.Disconnect:
- return false;
- default:
- return true;
- }
- }
- internal void SendRawData(NetPacket packet)
- {
- //2 - merge byte + minimal packet size + datalen(ushort)
- if (_peerListener.MergeEnabled &&
- CanMerge(packet.Property) &&
- _mergePos + packet.Size + NetConstants.HeaderSize*2 + 2 < _mtu)
- {
- FastBitConverter.GetBytes(_mergeData.RawData, _mergePos + NetConstants.HeaderSize, (ushort)packet.Size);
- Buffer.BlockCopy(packet.RawData, 0, _mergeData.RawData, _mergePos + NetConstants.HeaderSize + 2, packet.Size);
- _mergePos += packet.Size + 2;
- _mergeCount++;
- //DebugWriteForce("Merged: " + _mergePos + "/" + (_mtu - 2) + ", count: " + _mergeCount);
- return;
- }
- NetUtils.DebugWrite(ConsoleColor.DarkYellow, "[P]SendingPacket: " + packet.Property);
- _peerListener.SendRaw(packet.RawData, 0, packet.Size, _remoteEndPoint);
- }
- private void SendQueuedPackets(int currentMaxSend)
- {
- int currentSended = 0;
- while (currentSended < currentMaxSend)
- {
- //Get one of packets
- if (_reliableOrderedChannel.SendNextPacket() ||
- _reliableUnorderedChannel.SendNextPacket() ||
- _sequencedChannel.SendNextPacket() ||
- _simpleChannel.SendNextPacket())
- {
- currentSended++;
- }
- else
- {
- //no outgoing packets
- break;
- }
- }
- //Increase counter
- _sendedPacketsCount += currentSended;
- //If merging enabled
- if (_mergePos > 0)
- {
- if (_mergeCount > 1)
- {
- NetUtils.DebugWrite("Send merged: " + _mergePos + ", count: " + _mergeCount);
- _peerListener.SendRaw(_mergeData.RawData, 0, NetConstants.HeaderSize + _mergePos, _remoteEndPoint);
- }
- else
- {
- //Send without length information and merging
- _peerListener.SendRaw(_mergeData.RawData, NetConstants.HeaderSize + 2, _mergePos - 2, _remoteEndPoint);
- }
- _mergePos = 0;
- _mergeCount = 0;
- }
- }
- /// <summary>
- /// Flush all queued packets
- /// </summary>
- public void Flush()
- {
- lock (_flushLock)
- {
- SendQueuedPackets(int.MaxValue);
- }
- }
- internal void Update(int deltaTime)
- {
- if (_connectionState == ConnectionState.Disconnected)
- {
- return;
- }
- _timeSinceLastPacket += deltaTime;
- if (_connectionState == ConnectionState.InProgress)
- {
- _connectTimer += deltaTime;
- if (_connectTimer > _peerListener.ReconnectDelay)
- {
- _connectTimer = 0;
- _connectAttempts++;
- if (_connectAttempts > _peerListener.MaxConnectAttempts)
- {
- _connectionState = ConnectionState.Disconnected;
- return;
- }
- //else send connect again
- SendConnectRequest();
- }
- return;
- }
- //Get current flow mode
- int maxSendPacketsCount = _peerListener.GetPacketsPerSecond(_currentFlowMode);
- int currentMaxSend;
- if (maxSendPacketsCount > 0)
- {
- int availableSendPacketsCount = maxSendPacketsCount - _sendedPacketsCount;
- currentMaxSend = Math.Min(availableSendPacketsCount, (maxSendPacketsCount*deltaTime)/NetConstants.FlowUpdateTime);
- }
- else
- {
- currentMaxSend = int.MaxValue;
- }
- //DebugWrite("[UPDATE]Delta: {0}ms, MaxSend: {1}", deltaTime, currentMaxSend);
- //Pending acks
- _reliableOrderedChannel.SendAcks();
- _reliableUnorderedChannel.SendAcks();
- //ResetFlowTimer
- _flowTimer += deltaTime;
- if (_flowTimer >= NetConstants.FlowUpdateTime)
- {
- NetUtils.DebugWrite("[UPDATE]Reset flow timer, _sendedPackets - {0}", _sendedPacketsCount);
- _sendedPacketsCount = 0;
- _flowTimer = 0;
- }
- //Send ping
- _pingSendTimer += deltaTime;
- if (_pingSendTimer >= _peerListener.PingInterval)
- {
- NetUtils.DebugWrite("[PP] Send ping...");
- //reset timer
- _pingSendTimer = 0;
- //send ping
- CreateAndSend(PacketProperty.Ping, _pingSequence);
- //reset timer
- _pingTimeStart = DateTime.UtcNow;
- }
- //RTT - round trip time
- _rttResetTimer += deltaTime;
- if (_rttResetTimer >= RttResetDelay)
- {
- _rttResetTimer = 0;
- //Rtt update
- _rtt = _avgRtt;
- _ping = _avgRtt;
- _peerListener.ConnectionLatencyUpdated(this, _ping);
- _rttCount = 1;
- }
- //MTU - Maximum transmission unit
- if (!_finishMtu)
- {
- _mtuCheckTimer += deltaTime;
- if (_mtuCheckTimer >= MtuCheckDelay)
- {
- _mtuCheckTimer = 0;
- _mtuCheckAttempts++;
- if (_mtuCheckAttempts >= MaxMtuCheckAttempts)
- {
- _finishMtu = true;
- }
- else
- {
- lock (_mtuMutex)
- {
- //Send increased packet
- if (_mtuIdx < NetConstants.PossibleMtu.Length - 1)
- {
- int newMtu = NetConstants.PossibleMtu[_mtuIdx + 1] - NetConstants.HeaderSize;
- var p = _packetPool.Get(PacketProperty.MtuCheck, newMtu);
- p.RawData[1] = (byte)(_mtuIdx + 1);
- SendPacket(p);
- }
- }
- }
- }
- }
- //MTU - end
- //Pending send
- lock (_flushLock)
- {
- SendQueuedPackets(currentMaxSend);
- }
- }
- //For channels
- internal void Recycle(NetPacket packet)
- {
- _packetPool.Recycle(packet);
- }
- internal NetPacket GetPacketFromPool(PacketProperty property, int bytesCount)
- {
- return _packetPool.Get(property, bytesCount);
- }
- }
- }
- #endif
|