You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-06 02:11:06 +09:00
ConnectionLatencyUpdated message type added; WriteTime() ReadTime() added
This commit is contained in:
@@ -183,7 +183,7 @@ namespace Lidgren.Network
|
||||
m_peer.m_handshakes.Remove(m_remoteEndpoint); // TODO: make this more thread safe? we're on user thread
|
||||
}
|
||||
|
||||
internal void ReceivedHandshake(NetMessageType tp, int ptr, int payloadLength)
|
||||
internal void ReceivedHandshake(double now, NetMessageType tp, int ptr, int payloadLength)
|
||||
{
|
||||
m_peer.VerifyNetworkThread();
|
||||
|
||||
@@ -211,6 +211,7 @@ namespace Lidgren.Network
|
||||
{
|
||||
// ok, let's not add connection just yet
|
||||
NetIncomingMessage appMsg = m_peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionApproval, (m_remoteHailMessage == null ? 0 : m_remoteHailMessage.LengthBytes));
|
||||
appMsg.m_receiveTime = now;
|
||||
appMsg.m_senderConnection = this;
|
||||
appMsg.m_senderEndpoint = this.m_remoteEndpoint;
|
||||
if (m_remoteHailMessage != null)
|
||||
|
||||
@@ -9,11 +9,19 @@ namespace Lidgren.Network
|
||||
private float m_averageRoundtripTime;
|
||||
private float m_timeoutDeadline = float.MaxValue;
|
||||
|
||||
// local time value + m_remoteTimeOffset = remote time value
|
||||
internal double m_remoteTimeOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current average roundtrip time in seconds
|
||||
/// </summary>
|
||||
public float AverageRoundtripTime { get { return m_averageRoundtripTime; } }
|
||||
|
||||
internal double GetLocalTime(double remoteTimeStamp)
|
||||
{
|
||||
return remoteTimeStamp - m_remoteTimeOffset;
|
||||
}
|
||||
|
||||
internal void InitializePing()
|
||||
{
|
||||
// randomize ping sent time (0.25 - 1.0 x ping interval)
|
||||
@@ -27,11 +35,10 @@ namespace Lidgren.Network
|
||||
m_peer.VerifyNetworkThread();
|
||||
|
||||
m_sentPingNumber++;
|
||||
if (m_sentPingNumber >= 256)
|
||||
m_sentPingNumber = 0;
|
||||
|
||||
m_sentPingTime = (float)NetTime.Now;
|
||||
NetOutgoingMessage om = m_peer.CreateMessage(1);
|
||||
om.Write((byte)m_sentPingNumber);
|
||||
om.Write((byte)m_sentPingNumber); // truncating to 0-255
|
||||
om.m_messageType = NetMessageType.Ping;
|
||||
|
||||
int len = om.Encode(m_peer.m_sendBuffer, 0, 0);
|
||||
@@ -45,20 +52,22 @@ namespace Lidgren.Network
|
||||
{
|
||||
m_peer.VerifyNetworkThread();
|
||||
|
||||
NetOutgoingMessage om = m_peer.CreateMessage(1);
|
||||
NetOutgoingMessage om = m_peer.CreateMessage(5);
|
||||
om.Write((byte)pingNumber);
|
||||
om.Write((float)NetTime.Now); // we should update this value to reflect the exact point in time the packet is SENT
|
||||
om.m_messageType = NetMessageType.Pong;
|
||||
|
||||
int len = om.Encode(m_peer.m_sendBuffer, 0, 0);
|
||||
bool connectionReset;
|
||||
|
||||
m_peer.SendPacket(len, m_remoteEndpoint, 1, out connectionReset);
|
||||
|
||||
m_statistics.PacketSent(len, 1);
|
||||
}
|
||||
|
||||
internal void ReceivedPong(float now, int pongNumber)
|
||||
internal void ReceivedPong(float now, int pongNumber, float remoteSendTime)
|
||||
{
|
||||
if (pongNumber != m_sentPingNumber)
|
||||
if ((byte)pongNumber != (byte)m_sentPingNumber)
|
||||
{
|
||||
m_peer.LogVerbose("Ping/Pong mismatch; dropped message?");
|
||||
return;
|
||||
@@ -69,15 +78,20 @@ namespace Lidgren.Network
|
||||
float rtt = now - m_sentPingTime;
|
||||
NetException.Assert(rtt >= 0);
|
||||
|
||||
double diff = (remoteSendTime + (rtt / 2.0)) - now;
|
||||
|
||||
if (m_averageRoundtripTime < 0)
|
||||
{
|
||||
m_remoteTimeOffset = diff;
|
||||
m_averageRoundtripTime = rtt; // initial estimate
|
||||
m_peer.LogDebug("Initiated average roundtrip time to " + NetTime.ToReadable(m_averageRoundtripTime));
|
||||
m_peer.LogDebug("Initiated average roundtrip time to " + NetTime.ToReadable(m_averageRoundtripTime) + " Server time is: " + (now + diff));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_averageRoundtripTime = (m_averageRoundtripTime * 0.7f) + (float)(rtt * 0.3f);
|
||||
m_peer.LogVerbose("Updated average roundtrip time to " + NetTime.ToReadable(m_averageRoundtripTime));
|
||||
|
||||
m_remoteTimeOffset = ((m_remoteTimeOffset * (double)(m_sentPingNumber - 1)) + diff) / (double)m_sentPingNumber;
|
||||
m_peer.LogVerbose("Updated average roundtrip time to " + NetTime.ToReadable(m_averageRoundtripTime) + ", server time to " + (now + m_remoteTimeOffset) + " (ie. diff " + m_remoteTimeOffset + ")");
|
||||
}
|
||||
|
||||
// update resend delay for all channels
|
||||
@@ -89,7 +103,17 @@ namespace Lidgren.Network
|
||||
rchan.m_resendDelay = resendDelay;
|
||||
}
|
||||
|
||||
m_peer.LogVerbose("Timeout deadline pushed to " + m_timeoutDeadline);
|
||||
// m_peer.LogVerbose("Timeout deadline pushed to " + m_timeoutDeadline);
|
||||
|
||||
// notify the application that average rtt changed
|
||||
if (m_peer.m_configuration.IsMessageTypeEnabled(NetIncomingMessageType.ConnectionLatencyUpdated))
|
||||
{
|
||||
NetIncomingMessage update = m_peer.CreateIncomingMessage(NetIncomingMessageType.ConnectionLatencyUpdated, 4);
|
||||
update.m_senderConnection = this;
|
||||
update.m_senderEndpoint = this.m_remoteEndpoint;
|
||||
update.Write(rtt);
|
||||
m_peer.ReleaseMessage(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Lidgren.Network
|
||||
|
||||
internal void InitExpandMTU(double now)
|
||||
{
|
||||
m_lastSentMTUAttemptTime = now + m_peerConfiguration.m_expandMTUFrequency + 1.0f; // wait a tiny bit before starting to expand mtu
|
||||
m_lastSentMTUAttemptTime = now + m_peerConfiguration.m_expandMTUFrequency + 1.5f + m_averageRoundtripTime; // wait a tiny bit before starting to expand mtu
|
||||
m_largestSuccessfulMTU = 512;
|
||||
m_smallestFailedMTU = -1;
|
||||
m_currentMTU = m_peerConfiguration.MaximumTransmissionUnit;
|
||||
|
||||
@@ -138,10 +138,10 @@ namespace Lidgren.Network
|
||||
{
|
||||
if (now > m_sentPingTime + m_peer.m_configuration.m_pingInterval)
|
||||
SendPing();
|
||||
}
|
||||
|
||||
// handle expand mtu
|
||||
MTUExpansionHeartbeat(now);
|
||||
// handle expand mtu
|
||||
MTUExpansionHeartbeat(now);
|
||||
}
|
||||
|
||||
if (m_disconnectRequested)
|
||||
{
|
||||
@@ -352,8 +352,10 @@ namespace Lidgren.Network
|
||||
SendPong(pingNr);
|
||||
break;
|
||||
case NetMessageType.Pong:
|
||||
int pongNr = m_peer.m_receiveBuffer[ptr++];
|
||||
ReceivedPong(now, pongNr);
|
||||
NetIncomingMessage pmsg = m_peer.SetupReadHelperMessage(ptr, payloadLength);
|
||||
int pongNr = pmsg.ReadByte();
|
||||
float remoteSendTime = pmsg.ReadSingle();
|
||||
ReceivedPong(now, pongNr, remoteSendTime);
|
||||
break;
|
||||
case NetMessageType.ExpandMTURequest:
|
||||
SendMTUSuccess(payloadLength);
|
||||
|
||||
@@ -465,6 +465,20 @@ namespace Lidgren.Network
|
||||
return new IPEndPoint(address, port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a value, in local time comparable to NetTime.Now, written using WriteTime()
|
||||
/// Must have a connected sender
|
||||
/// </summary>
|
||||
public double ReadTime(bool highPrecision)
|
||||
{
|
||||
double remoteTime = (highPrecision ? ReadDouble() : (double)ReadSingle());
|
||||
|
||||
if (m_senderConnection == null)
|
||||
throw new NetException("Cannot call ReadTime() on message without a connected sender (ie. unconnected messages)");
|
||||
|
||||
return remoteTime - m_senderConnection.m_remoteTimeOffset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pads data with enough bits to reach a full byte. Decreases cpu usage for subsequent byte writes.
|
||||
/// </summary>
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Lidgren.Network
|
||||
internal int m_sequenceNumber;
|
||||
internal NetMessageType m_receivedMessageType;
|
||||
internal bool m_isFragment;
|
||||
internal double m_receiveTime;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of this incoming message
|
||||
@@ -62,6 +63,11 @@ namespace Lidgren.Network
|
||||
/// </summary>
|
||||
public NetConnection SenderConnection { get { return m_senderConnection; } }
|
||||
|
||||
/// <summary>
|
||||
/// What local time the message was received from the network
|
||||
/// </summary>
|
||||
public double ReceiveTime { get { return m_receiveTime; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the message payload in bytes
|
||||
/// </summary>
|
||||
|
||||
@@ -42,5 +42,6 @@ namespace Lidgren.Network
|
||||
WarningMessage = 1 << 9, // Data (string)
|
||||
ErrorMessage = 1 << 10, // Data (string)
|
||||
NatIntroductionSuccess = 1 << 11, // Data (as passed to master server)
|
||||
ConnectionLatencyUpdated = 1 << 12, // Seconds as a Single
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,6 +534,17 @@ namespace Lidgren.Network
|
||||
Write((ushort)endPoint.Port);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the local time to a message; readable (and convertable to local time) by the remote host using ReadTime()
|
||||
/// </summary>
|
||||
public void WriteTime(double localTime, bool highPrecision)
|
||||
{
|
||||
if (highPrecision)
|
||||
Write(localTime);
|
||||
else
|
||||
Write((float)localTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pads data with enough bits to reach a full byte. Decreases cpu usage for subsequent byte writes.
|
||||
/// </summary>
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Lidgren.Network
|
||||
Buffer.BlockCopy(im.m_data, ptr, info.Data, offset, im.LengthBytes - ptr);
|
||||
|
||||
int cnt = info.ReceivedChunks.Count();
|
||||
//Console.WriteLine("Found fragment #" + chunkNumber + " in group " + group + " offset " + offset + " of total bits " + totalBits + " (total chunks done " + cnt + ")");
|
||||
//LogVerbose("Found fragment #" + chunkNumber + " in group " + group + " offset " + offset + " of total bits " + totalBits + " (total chunks done " + cnt + ")");
|
||||
|
||||
LogVerbose("Received fragment " + chunkNumber + " of " + totalNumChunks + " (" + cnt + " chunks received)");
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@ namespace Lidgren.Network
|
||||
{
|
||||
NetException.Assert(msg.m_incomingMessageType != NetIncomingMessageType.Error);
|
||||
|
||||
if (msg.MessageType == NetIncomingMessageType.UnconnectedData)
|
||||
Console.WriteLine("x");
|
||||
|
||||
if (msg.m_isFragment)
|
||||
{
|
||||
HandleReleasedFragment(msg);
|
||||
@@ -306,6 +303,7 @@ namespace Lidgren.Network
|
||||
NetConnection sender = null;
|
||||
m_connectionLookup.TryGetValue(ipsender, out sender);
|
||||
|
||||
double receiveTime = NetTime.Now;
|
||||
//
|
||||
// parse packet into messages
|
||||
//
|
||||
@@ -344,7 +342,7 @@ namespace Lidgren.Network
|
||||
if (sender != null)
|
||||
sender.ReceivedLibraryMessage(tp, ptr, payloadByteLength);
|
||||
else
|
||||
ReceivedUnconnectedLibraryMessage(ipsender, tp, ptr, payloadByteLength);
|
||||
ReceivedUnconnectedLibraryMessage(receiveTime, ipsender, tp, ptr, payloadByteLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -353,6 +351,7 @@ namespace Lidgren.Network
|
||||
|
||||
NetIncomingMessage msg = CreateIncomingMessage(NetIncomingMessageType.Data, payloadByteLength);
|
||||
msg.m_isFragment = isFragment;
|
||||
msg.m_receiveTime = receiveTime;
|
||||
msg.m_sequenceNumber = sequenceNumber;
|
||||
msg.m_receivedMessageType = tp;
|
||||
msg.m_senderConnection = sender;
|
||||
@@ -390,12 +389,12 @@ namespace Lidgren.Network
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceivedUnconnectedLibraryMessage(IPEndPoint senderEndpoint, NetMessageType tp, int ptr, int payloadByteLength)
|
||||
private void ReceivedUnconnectedLibraryMessage(double now, IPEndPoint senderEndpoint, NetMessageType tp, int ptr, int payloadByteLength)
|
||||
{
|
||||
NetConnection shake;
|
||||
if (m_handshakes.TryGetValue(senderEndpoint, out shake))
|
||||
{
|
||||
shake.ReceivedHandshake(tp, ptr, payloadByteLength);
|
||||
shake.ReceivedHandshake(now, tp, ptr, payloadByteLength);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -410,6 +409,7 @@ namespace Lidgren.Network
|
||||
NetIncomingMessage dm = CreateIncomingMessage(NetIncomingMessageType.DiscoveryRequest, payloadByteLength);
|
||||
if (payloadByteLength > 0)
|
||||
Buffer.BlockCopy(m_receiveBuffer, ptr, dm.m_data, 0, payloadByteLength);
|
||||
dm.m_receiveTime = now;
|
||||
dm.m_bitLength = payloadByteLength * 8;
|
||||
dm.m_senderEndpoint = senderEndpoint;
|
||||
ReleaseMessage(dm);
|
||||
@@ -422,6 +422,7 @@ namespace Lidgren.Network
|
||||
NetIncomingMessage dr = CreateIncomingMessage(NetIncomingMessageType.DiscoveryResponse, payloadByteLength);
|
||||
if (payloadByteLength > 0)
|
||||
Buffer.BlockCopy(m_receiveBuffer, ptr, dr.m_data, 0, payloadByteLength);
|
||||
dr.m_receiveTime = now;
|
||||
dr.m_bitLength = payloadByteLength * 8;
|
||||
dr.m_senderEndpoint = senderEndpoint;
|
||||
ReleaseMessage(dr);
|
||||
@@ -460,7 +461,7 @@ namespace Lidgren.Network
|
||||
// Ok, start handshake!
|
||||
NetConnection conn = new NetConnection(this, senderEndpoint);
|
||||
m_handshakes.Add(senderEndpoint, conn);
|
||||
conn.ReceivedHandshake(tp, ptr, payloadByteLength);
|
||||
conn.ReceivedHandshake(now, tp, ptr, payloadByteLength);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Lidgren.Network
|
||||
//
|
||||
// default values
|
||||
//
|
||||
m_disabledTypes = NetIncomingMessageType.ConnectionApproval | NetIncomingMessageType.UnconnectedData | NetIncomingMessageType.VerboseDebugMessage;
|
||||
m_disabledTypes = NetIncomingMessageType.ConnectionApproval | NetIncomingMessageType.UnconnectedData | NetIncomingMessageType.VerboseDebugMessage | NetIncomingMessageType.ConnectionLatencyUpdated;
|
||||
m_networkThreadName = "Lidgren network thread";
|
||||
m_localAddress = IPAddress.Any;
|
||||
m_port = 0;
|
||||
|
||||
Reference in New Issue
Block a user