From 6a30a001728d31c2d45621157c026171f3edb864 Mon Sep 17 00:00:00 2001 From: lidgren Date: Wed, 3 Nov 2010 10:38:13 +0000 Subject: [PATCH] Added some optimizations --- Lidgren.Network/NetConnection.Handshake.cs | 4 +- Lidgren.Network/NetConnection.Latency.cs | 9 ++ Lidgren.Network/NetConnection.cs | 106 +++++++++++--------- Lidgren.Network/NetPeer.Internal.cs | 20 ++-- Lidgren.Network/NetPeerConfiguration.cs | 2 +- Lidgren.Network/NetReliableSenderChannel.cs | 8 +- 6 files changed, 87 insertions(+), 62 deletions(-) diff --git a/Lidgren.Network/NetConnection.Handshake.cs b/Lidgren.Network/NetConnection.Handshake.cs index 9ca2c6c..0b8625f 100644 --- a/Lidgren.Network/NetConnection.Handshake.cs +++ b/Lidgren.Network/NetConnection.Handshake.cs @@ -228,7 +228,7 @@ namespace Lidgren.Network SendConnectResponse(true); return; } - m_peer.LogDebug("Unhandled handshake: " + tp + ", status is " + m_status + " length: " + payloadLength); + m_peer.LogDebug("Unhandled Connect: " + tp + ", status is " + m_status + " length: " + payloadLength); break; case NetMessageType.ConnectResponse: switch (m_status) @@ -303,7 +303,7 @@ namespace Lidgren.Network SetStatus(NetConnectionStatus.Disconnected, reason); break; default: - m_peer.LogDebug("Unhandled handshake: " + tp + " length: " + payloadLength); + m_peer.LogDebug("Unhandled type during handshake: " + tp + " length: " + payloadLength); break; } } diff --git a/Lidgren.Network/NetConnection.Latency.cs b/Lidgren.Network/NetConnection.Latency.cs index 389b13d..d8ad4ac 100644 --- a/Lidgren.Network/NetConnection.Latency.cs +++ b/Lidgren.Network/NetConnection.Latency.cs @@ -68,6 +68,15 @@ namespace Lidgren.Network m_peer.LogVerbose("Updated average roundtrip time to " + NetTime.ToReadable(m_averageRoundtripTime)); } + // update resend delay for all channels + float resendDelay = GetResendDelay(); + foreach (var chan in m_sendChannels) + { + var rchan = chan as NetReliableSenderChannel; + if (rchan != null) + rchan.m_resendDelay = resendDelay; + } + m_peer.LogVerbose("Timeout deadline pushed to " + m_timeoutDeadline); } } diff --git a/Lidgren.Network/NetConnection.cs b/Lidgren.Network/NetConnection.cs index 5cce58c..8d3009f 100644 --- a/Lidgren.Network/NetConnection.cs +++ b/Lidgren.Network/NetConnection.cs @@ -115,26 +115,29 @@ namespace Lidgren.Network } } - internal void Heartbeat(float now) + internal void Heartbeat(float now, uint frameCounter) { m_peer.VerifyNetworkThread(); NetException.Assert(m_status != NetConnectionStatus.InitiatedConnect && m_status != NetConnectionStatus.RespondedConnect); - if (now > m_timeoutDeadline) + if ((frameCounter % 5) == 0) { - // - // connection timed out - // - m_peer.LogVerbose("Connection timed out at " + now + " deadline was " + m_timeoutDeadline); - ExecuteDisconnect("Connection timed out", true); - } + if (now > m_timeoutDeadline) + { + // + // connection timed out + // + m_peer.LogVerbose("Connection timed out at " + now + " deadline was " + m_timeoutDeadline); + ExecuteDisconnect("Connection timed out", true); + } - // send ping? - if (m_status == NetConnectionStatus.Connected) - { - if (now > m_sentPingTime + m_peer.m_configuration.m_pingInterval) - SendPing(); + // send ping? + if (m_status == NetConnectionStatus.Connected) + { + if (now > m_sentPingTime + m_peer.m_configuration.m_pingInterval) + SendPing(); + } } bool connectionReset; // TODO: handle connection reset @@ -146,48 +149,51 @@ namespace Lidgren.Network byte[] sendBuffer = m_peer.m_sendBuffer; int mtu = m_peerConfiguration.m_maximumTransmissionUnit; - // - // send ack messages - // - while (m_queuedAcks.Count > 0) + if ((frameCounter % 3) == 0) // coalesce a few frames { - int acks = (mtu - (m_sendBufferWritePtr + 5)) / 3; // 3 bytes per actual ack - if (acks > m_queuedAcks.Count) - acks = m_queuedAcks.Count; - - NetException.Assert(acks > 0); - - m_sendBufferNumMessages++; - - // write acks header - sendBuffer[m_sendBufferWritePtr++] = (byte)NetMessageType.Acknowledge; - sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number - sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number - int len = (acks * 3) * 8; // bits - sendBuffer[m_sendBufferWritePtr++] = (byte)len; - sendBuffer[m_sendBufferWritePtr++] = (byte)(len >> 8); - - // write acks - for(int i=0;i 0) { - NetTuple tuple; - m_queuedAcks.TryDequeue(out tuple); + int acks = (mtu - (m_sendBufferWritePtr + 5)) / 3; // 3 bytes per actual ack + if (acks > m_queuedAcks.Count) + acks = m_queuedAcks.Count; - //m_peer.LogVerbose("Sending ack for " + tuple.Item1 + "#" + tuple.Item2); + NetException.Assert(acks > 0); - sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item1; - sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item2; - sendBuffer[m_sendBufferWritePtr++] = (byte)(tuple.Item2 >> 8); - } + m_sendBufferNumMessages++; - if (m_queuedAcks.Count > 0) - { - // send packet and go for another round of acks - NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); - m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndpoint, m_sendBufferNumMessages, out connectionReset); - m_statistics.PacketSent(m_sendBufferWritePtr, 1); - m_sendBufferWritePtr = 0; - m_sendBufferNumMessages = 0; + // write acks header + sendBuffer[m_sendBufferWritePtr++] = (byte)NetMessageType.Acknowledge; + sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number + sendBuffer[m_sendBufferWritePtr++] = 0; // no sequence number + int len = (acks * 3) * 8; // bits + sendBuffer[m_sendBufferWritePtr++] = (byte)len; + sendBuffer[m_sendBufferWritePtr++] = (byte)(len >> 8); + + // write acks + for (int i = 0; i < acks; i++) + { + NetTuple tuple; + m_queuedAcks.TryDequeue(out tuple); + + //m_peer.LogVerbose("Sending ack for " + tuple.Item1 + "#" + tuple.Item2); + + sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item1; + sendBuffer[m_sendBufferWritePtr++] = (byte)tuple.Item2; + sendBuffer[m_sendBufferWritePtr++] = (byte)(tuple.Item2 >> 8); + } + + if (m_queuedAcks.Count > 0) + { + // send packet and go for another round of acks + NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); + m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndpoint, m_sendBufferNumMessages, out connectionReset); + m_statistics.PacketSent(m_sendBufferWritePtr, 1); + m_sendBufferWritePtr = 0; + m_sendBufferNumMessages = 0; + } } } diff --git a/Lidgren.Network/NetPeer.Internal.cs b/Lidgren.Network/NetPeer.Internal.cs index b193b7a..857131c 100644 --- a/Lidgren.Network/NetPeer.Internal.cs +++ b/Lidgren.Network/NetPeer.Internal.cs @@ -20,6 +20,7 @@ namespace Lidgren.Network internal NetIncomingMessage m_readHelperMessage; private EndPoint m_senderRemote; private object m_initializeLock = new object(); + private uint m_frameCounter; internal readonly NetPeerConfiguration m_configuration; private readonly NetQueue m_releasedIncomingMessages; @@ -195,12 +196,17 @@ namespace Lidgren.Network float now = (float)NetTime.Now; + m_frameCounter++; + // do handshake heartbeats - foreach (NetConnection conn in m_handshakes.Values) + if ((m_frameCounter % 3) == 0) { - conn.UnconnectedHeartbeat(now); - if (conn.m_status == NetConnectionStatus.Connected || conn.m_status == NetConnectionStatus.Disconnected) - break; // collection is modified + foreach (NetConnection conn in m_handshakes.Values) + { + conn.UnconnectedHeartbeat(now); + if (conn.m_status == NetConnectionStatus.Connected || conn.m_status == NetConnectionStatus.Disconnected) + break; // collection has been modified + } } #if DEBUG @@ -212,7 +218,7 @@ namespace Lidgren.Network { foreach (NetConnection conn in m_connections) { - conn.Heartbeat(now); + conn.Heartbeat(now, m_frameCounter); if (conn.m_status == NetConnectionStatus.Disconnected) { // @@ -246,7 +252,7 @@ namespace Lidgren.Network if (m_socket == null) return; - if (!m_socket.Poll(500, SelectMode.SelectRead)) // wait up to 1/2 ms for data to arrive + if (!m_socket.Poll(1000, SelectMode.SelectRead)) // wait up to 1 ms for data to arrive return; //if (m_socket == null || m_socket.Available < 1) @@ -359,7 +365,7 @@ namespace Lidgren.Network } catch (Exception ex) { - LogError("Packet parsing error: " + ex.Message); + LogError("Packet parsing error: " + ex.Message + " from " + ipsender); } ptr += payloadByteLength; } diff --git a/Lidgren.Network/NetPeerConfiguration.cs b/Lidgren.Network/NetPeerConfiguration.cs index c16c9b3..5898f9c 100644 --- a/Lidgren.Network/NetPeerConfiguration.cs +++ b/Lidgren.Network/NetPeerConfiguration.cs @@ -70,7 +70,7 @@ namespace Lidgren.Network m_acceptIncomingConnections = false; m_maximumConnections = 32; m_defaultOutgoingMessageCapacity = 16; - m_pingInterval = 3.0f; + m_pingInterval = 4.0f; m_connectionTimeout = 25.0f; m_useMessageRecycling = true; diff --git a/Lidgren.Network/NetReliableSenderChannel.cs b/Lidgren.Network/NetReliableSenderChannel.cs index 69206d2..112f5f6 100644 --- a/Lidgren.Network/NetReliableSenderChannel.cs +++ b/Lidgren.Network/NetReliableSenderChannel.cs @@ -16,6 +16,8 @@ namespace Lidgren.Network private NetBitVector m_receivedAcks; internal NetStoredReliableMessage[] m_storedMessages; + internal float m_resendDelay; + internal override int WindowSize { get { return m_windowSize; } } internal NetReliableSenderChannel(NetConnection connection, int windowSize) @@ -27,6 +29,7 @@ namespace Lidgren.Network m_receivedAcks = new NetBitVector(NetConstants.NumSequenceNumbers); m_storedMessages = new NetStoredReliableMessage[m_windowSize]; m_queuedSends = new NetQueue(8); + m_resendDelay = m_connection.GetResendDelay(); } internal override int GetAllowedSends() @@ -60,8 +63,9 @@ namespace Lidgren.Network // call this regularely internal override void SendQueuedMessages(float now) { + // // resends - float resendDelay = m_connection.GetResendDelay(); + // for (int i = 0; i < m_storedMessages.Length; i++) { NetOutgoingMessage om = m_storedMessages[i].Message; @@ -69,7 +73,7 @@ namespace Lidgren.Network continue; float t = m_storedMessages[i].LastSent; - if (t > 0 && (now - t) > resendDelay) + if (t > 0 && (now - t) > m_resendDelay) { // deduce sequence number int startSlot = m_windowStart % m_windowSize;