Send order queue length in ping responses.
This commit is contained in:
@@ -304,12 +304,11 @@ namespace OpenRA.Network
|
|||||||
orderManager.ReceiveDisconnect(disconnect.ClientId, disconnect.Frame);
|
orderManager.ReceiveDisconnect(disconnect.ClientId, disconnect.Frame);
|
||||||
else if (OrderIO.TryParseSync(p.Data, out var sync))
|
else if (OrderIO.TryParseSync(p.Data, out var sync))
|
||||||
orderManager.ReceiveSync(sync);
|
orderManager.ReceiveSync(sync);
|
||||||
else if (OrderIO.TryParsePing(p.FromClient, p.Data, out var ping))
|
else if (OrderIO.TryParsePingRequest(p, out var timestamp))
|
||||||
{
|
{
|
||||||
// The Ping packet is sent back directly without changes
|
|
||||||
// Note that processing this here, rather than in NetworkConnectionReceive,
|
// Note that processing this here, rather than in NetworkConnectionReceive,
|
||||||
// so that poor world tick performance can be reflected in the latency measurement
|
// so that poor world tick performance can be reflected in the latency measurement
|
||||||
Send(ping);
|
Send(OrderIO.SerializePingResponse(timestamp, (byte)orderManager.OrderQueueLength));
|
||||||
record = false;
|
record = false;
|
||||||
}
|
}
|
||||||
else if (OrderIO.TryParseAck(p, out var ackFrame, out var ackCount))
|
else if (OrderIO.TryParseAck(p, out var ackFrame, out var ackCount))
|
||||||
|
|||||||
@@ -93,6 +93,16 @@ namespace OpenRA.Network
|
|||||||
return ms.GetBuffer();
|
return ms.GetBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] SerializePingResponse(long timestamp, byte queueLength)
|
||||||
|
{
|
||||||
|
var ms = new MemoryStream(14);
|
||||||
|
ms.WriteArray(BitConverter.GetBytes(0));
|
||||||
|
ms.WriteByte((byte)OrderType.Ping);
|
||||||
|
ms.WriteArray(BitConverter.GetBytes(timestamp));
|
||||||
|
ms.WriteByte(queueLength);
|
||||||
|
return ms.GetBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
public static bool TryParseDisconnect((int FromClient, byte[] Data) packet, out (int Frame, int ClientId) disconnect)
|
public static bool TryParseDisconnect((int FromClient, byte[] Data) packet, out (int Frame, int ClientId) disconnect)
|
||||||
{
|
{
|
||||||
// Valid Disconnect packets are only ever generated by the server
|
// Valid Disconnect packets are only ever generated by the server
|
||||||
@@ -123,24 +133,24 @@ namespace OpenRA.Network
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryParsePing(int fromClient, byte[] packet, out byte[] ping)
|
public static bool TryParsePingRequest((int FromClient, byte[] Data) packet, out long timestamp)
|
||||||
{
|
{
|
||||||
// Valid Ping packets are only ever generated by the server
|
// Valid Ping requests are only ever generated by the server
|
||||||
if (fromClient != 0 || packet.Length != 13 || packet[4] != (byte)OrderType.Ping)
|
if (packet.FromClient != 0 || packet.Data.Length != 13 || packet.Data[4] != (byte)OrderType.Ping)
|
||||||
{
|
{
|
||||||
ping = null;
|
timestamp = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid Ping packets always have frame 0
|
// Valid Ping packets always have frame 0
|
||||||
var frame = BitConverter.ToInt32(packet, 0);
|
var frame = BitConverter.ToInt32(packet.Data, 0);
|
||||||
if (frame != 0)
|
if (frame != 0)
|
||||||
{
|
{
|
||||||
ping = null;
|
timestamp = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ping = packet;
|
timestamp = BitConverter.ToInt64(packet.Data, 5);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace OpenRA.Network
|
|||||||
public Session LobbyInfo = new Session();
|
public Session LobbyInfo = new Session();
|
||||||
public Session.Client LocalClient => LobbyInfo.ClientWithIndex(Connection.LocalClientId);
|
public Session.Client LocalClient => LobbyInfo.ClientWithIndex(Connection.LocalClientId);
|
||||||
public World World;
|
public World World;
|
||||||
|
public int OrderQueueLength => pendingOrders.Count > 0 ? pendingOrders.Min(q => q.Value.Count) : 0;
|
||||||
|
|
||||||
public string ServerError = null;
|
public string ServerError = null;
|
||||||
public bool AuthenticationFailed = false;
|
public bool AuthenticationFailed = false;
|
||||||
|
|||||||
@@ -128,13 +128,13 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
// Ping packets are sent and processed internally within this thread to reduce
|
// Ping packets are sent and processed internally within this thread to reduce
|
||||||
// server-introduced latencies from polling loops
|
// server-introduced latencies from polling loops
|
||||||
if (expectLength == 9 && bytes[0] == (byte)OrderType.Ping)
|
if (expectLength == 10 && bytes[0] == (byte)OrderType.Ping)
|
||||||
{
|
{
|
||||||
if (pingHistory.Count == MaxPingSamples)
|
if (pingHistory.Count == MaxPingSamples)
|
||||||
pingHistory.Dequeue();
|
pingHistory.Dequeue();
|
||||||
|
|
||||||
pingHistory.Enqueue((int)(Game.RunTime - BitConverter.ToInt64(bytes, 1)));
|
pingHistory.Enqueue((int)(Game.RunTime - BitConverter.ToInt64(bytes, 1)));
|
||||||
server.OnConnectionPing(this, pingHistory.ToArray());
|
server.OnConnectionPing(this, pingHistory.ToArray(), bytes[9]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
server.OnConnectionPacket(this, frame, bytes);
|
server.OnConnectionPacket(this, frame, bytes);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace OpenRA.Server
|
|||||||
// - byte containing the number of sent order packets to apply
|
// - byte containing the number of sent order packets to apply
|
||||||
// - 0x20: Ping
|
// - 0x20: Ping
|
||||||
// - Int64 containing the server timestamp when the ping was generated
|
// - Int64 containing the server timestamp when the ping was generated
|
||||||
|
// - [client -> server only] byte containing the number of frames ready to simulate
|
||||||
//
|
//
|
||||||
// A connection handshake begins when a client opens a connection to the server:
|
// A connection handshake begins when a client opens a connection to the server:
|
||||||
// - Server sends:
|
// - Server sends:
|
||||||
|
|||||||
@@ -323,9 +323,9 @@ namespace OpenRA.Server
|
|||||||
events.Add(new ConnectionPacketEvent(conn, frame, data));
|
events.Add(new ConnectionPacketEvent(conn, frame, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnConnectionPing(Connection conn, int[] pingHistory)
|
internal void OnConnectionPing(Connection conn, int[] pingHistory, byte queueLength)
|
||||||
{
|
{
|
||||||
events.Add(new ConnectionPingEvent(conn, pingHistory));
|
events.Add(new ConnectionPingEvent(conn, pingHistory, queueLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OnConnectionDisconnect(Connection conn)
|
internal void OnConnectionDisconnect(Connection conn)
|
||||||
@@ -1021,7 +1021,7 @@ namespace OpenRA.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReceivePing(Connection conn, int[] pingHistory)
|
public void ReceivePing(Connection conn, int[] pingHistory, byte queueLength)
|
||||||
{
|
{
|
||||||
// Levels set relative to the default order lag of 3 net ticks (360ms)
|
// Levels set relative to the default order lag of 3 net ticks (360ms)
|
||||||
// TODO: Adjust this once dynamic lag is implemented
|
// TODO: Adjust this once dynamic lag is implemented
|
||||||
@@ -1367,16 +1367,18 @@ namespace OpenRA.Server
|
|||||||
{
|
{
|
||||||
readonly Connection connection;
|
readonly Connection connection;
|
||||||
readonly int[] pingHistory;
|
readonly int[] pingHistory;
|
||||||
|
readonly byte queueLength;
|
||||||
|
|
||||||
public ConnectionPingEvent(Connection connection, int[] pingHistory)
|
public ConnectionPingEvent(Connection connection, int[] pingHistory, byte queueLength)
|
||||||
{
|
{
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.pingHistory = pingHistory;
|
this.pingHistory = pingHistory;
|
||||||
|
this.queueLength = queueLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IServerEvent.Invoke(Server server)
|
void IServerEvent.Invoke(Server server)
|
||||||
{
|
{
|
||||||
server.ReceivePing(connection, pingHistory);
|
server.ReceivePing(connection, pingHistory, queueLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user