Overhaul client latency calculations.
The ping/pong orders are replaced with a dedicated (and much smaller) Ping packet that is handled directly in the client and server Connection wrappers. This allows clients to respond when the orders are processed, instead of queuing the pong order to be sent in the next frame (which added an extra 120ms of unwanted latency). The ping frequency has been raised to 1Hz, and pings are now routed through the server events queue in preparation for the future dynamic latency system. The raw ping numbers are no longer sent to clients, the server instead evaluates a single ConnectionQuality value that in the future may be based on more than just the ping times.
This commit is contained in:
@@ -272,12 +272,6 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
server.LobbyInfo.Clients.Remove(occupant);
|
||||
server.SyncLobbyClients();
|
||||
var ping = server.LobbyInfo.PingFromClient(occupant);
|
||||
if (ping != null)
|
||||
{
|
||||
server.LobbyInfo.ClientPings.Remove(ping);
|
||||
server.SyncClientPing();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -311,15 +305,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
// Slot may have a bot in it
|
||||
var occupant = server.LobbyInfo.ClientInSlot(s);
|
||||
if (occupant != null && occupant.Bot != null)
|
||||
{
|
||||
server.LobbyInfo.Clients.Remove(occupant);
|
||||
var ping = server.LobbyInfo.PingFromClient(occupant);
|
||||
if (ping != null)
|
||||
{
|
||||
server.LobbyInfo.ClientPings.Remove(ping);
|
||||
server.SyncClientPing();
|
||||
}
|
||||
}
|
||||
|
||||
server.SyncLobbyClients();
|
||||
|
||||
|
||||
@@ -21,9 +21,6 @@ namespace OpenRA.Mods.Common.Server
|
||||
static readonly int ConnReportInterval = 20000; // Report every 20 seconds
|
||||
static readonly int ConnTimeout = 60000; // Drop unresponsive clients after 60 seconds
|
||||
|
||||
// TickTimeout is in microseconds
|
||||
public int TickTimeout => PingInterval * 100;
|
||||
|
||||
long lastPing = 0;
|
||||
long lastConnReport = 0;
|
||||
bool isInitialPing = true;
|
||||
@@ -40,13 +37,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
lock (server.LobbyInfo)
|
||||
nonBotClientCount = server.LobbyInfo.NonBotClients.Count();
|
||||
|
||||
if (nonBotClientCount < 2 && server.Type != ServerType.Dedicated)
|
||||
{
|
||||
foreach (var c in server.Conns.ToList())
|
||||
if (c.Validated)
|
||||
server.SendOrderTo(c, "Ping", Game.RunTime.ToString());
|
||||
}
|
||||
else
|
||||
if (nonBotClientCount >= 2 || server.Type == ServerType.Dedicated)
|
||||
{
|
||||
foreach (var c in server.Conns.ToList())
|
||||
{
|
||||
@@ -63,7 +54,6 @@ namespace OpenRA.Mods.Common.Server
|
||||
|
||||
if (c.TimeSinceLastResponse < ConnTimeout)
|
||||
{
|
||||
server.SendOrderTo(c, "Ping", Game.RunTime.ToString());
|
||||
if (!c.TimeoutMessageShown && c.TimeSinceLastResponse > PingInterval * 2)
|
||||
{
|
||||
server.SendMessage(client.Name + " is experiencing connection problems.");
|
||||
|
||||
@@ -34,9 +34,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
widget.Bounds.Width = latency.Bounds.X + latencyFont.Measure(latency.GetText()).X + rightMargin;
|
||||
};
|
||||
|
||||
var ping = orderManager.LobbyInfo.PingFromClient(client);
|
||||
latency.GetText = () => LobbyUtils.LatencyDescription(ping);
|
||||
latency.GetColor = () => LobbyUtils.LatencyColor(ping);
|
||||
latency.GetText = () => LobbyUtils.LatencyDescription(client);
|
||||
latency.GetColor = () => LobbyUtils.LatencyColor(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,34 +306,32 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
return AvailableSpawnPoints(spawnPoints, lobbyInfo).Count < lobbyInfo.Clients.Count(c => !c.IsObserver);
|
||||
}
|
||||
|
||||
public static Color LatencyColor(Session.ClientPing ping)
|
||||
public static Color LatencyColor(Session.Client client)
|
||||
{
|
||||
if (ping == null)
|
||||
if (client == null)
|
||||
return Color.Gray;
|
||||
|
||||
// Levels set relative to the default order lag of 3 net ticks (360ms)
|
||||
// TODO: Adjust this once dynamic lag is implemented
|
||||
if (ping.Latency < 0)
|
||||
return Color.Gray;
|
||||
if (ping.Latency < 300)
|
||||
return Color.LimeGreen;
|
||||
if (ping.Latency < 600)
|
||||
return Color.Orange;
|
||||
return Color.Red;
|
||||
switch (client.ConnectionQuality)
|
||||
{
|
||||
case Session.ConnectionQuality.Good: return Color.LimeGreen;
|
||||
case Session.ConnectionQuality.Moderate: return Color.Orange;
|
||||
case Session.ConnectionQuality.Poor: return Color.Red;
|
||||
default: return Color.Gray;
|
||||
}
|
||||
}
|
||||
|
||||
public static string LatencyDescription(Session.ClientPing ping)
|
||||
public static string LatencyDescription(Session.Client client)
|
||||
{
|
||||
if (ping == null)
|
||||
if (client == null)
|
||||
return "Unknown";
|
||||
|
||||
if (ping.Latency < 0)
|
||||
return "Unknown";
|
||||
if (ping.Latency < 300)
|
||||
return "Good";
|
||||
if (ping.Latency < 600)
|
||||
return "Moderate";
|
||||
return "Poor";
|
||||
switch (client.ConnectionQuality)
|
||||
{
|
||||
case Session.ConnectionQuality.Good: return "Good";
|
||||
case Session.ConnectionQuality.Moderate: return "Moderate";
|
||||
case Session.ConnectionQuality.Poor: return "Poor";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetupLatencyWidget(Widget parent, Session.Client c, OrderManager orderManager)
|
||||
@@ -345,8 +343,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
block.IsVisible = () => visible;
|
||||
|
||||
if (visible)
|
||||
block.Get<ColorBlockWidget>("LATENCY_COLOR").GetColor = () => LatencyColor(
|
||||
orderManager.LobbyInfo.PingFromClient(c));
|
||||
block.Get<ColorBlockWidget>("LATENCY_COLOR").GetColor = () => LatencyColor(c);
|
||||
}
|
||||
|
||||
var tooltip = parent.Get<ClientTooltipRegionWidget>("LATENCY_REGION");
|
||||
|
||||
Reference in New Issue
Block a user