From 8c657e48377213e7ee66c05a4047085cee6084ea Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 14 Aug 2014 20:41:36 +0100 Subject: [PATCH] add a estimator of client ping time, and painfully make it visible in show connections console command --- OpenSim/Framework/IClientAPI.cs | 2 ++ OpenSim/Region/Application/OpenSim.cs | 4 +++- .../ClientStack/Linden/UDP/LLClientView.cs | 12 ++++++++++++ .../ClientStack/Linden/UDP/LLUDPClient.cs | 16 ++++++++++++++++ .../ClientStack/Linden/UDP/LLUDPServer.cs | 18 +++++++++++++----- .../Server/IRCClientView.cs | 2 ++ .../OptionalModules/World/NPC/NPCAvatar.cs | 2 ++ OpenSim/Tests/Common/Mock/TestClient.cs | 2 ++ 8 files changed, 52 insertions(+), 6 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 22cc79da33..3b0430bed0 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -755,6 +755,8 @@ namespace OpenSim.Framework /// bool IsActive { get; set; } + int PingTimeMS { get; } + /// /// Set if the client is closing due to a logout request /// diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 85049c9e56..13d817020c 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -978,6 +978,7 @@ namespace OpenSim cdt.AddColumn("Circuit code", 12); cdt.AddColumn("Endpoint", 23); cdt.AddColumn("Active?", 7); + cdt.AddColumn("ping(ms)", 8); SceneManager.ForEachScene( s => s.ForEachClient( @@ -986,7 +987,8 @@ namespace OpenSim c.Name, c.CircuitCode.ToString(), c.RemoteEndPoint.ToString(), - c.IsActive.ToString()))); + c.IsActive.ToString(), + c.PingTimeMS))); MainConsole.Instance.Output(cdt.ToString()); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 59d1c69137..e69bf2322e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -419,6 +419,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } } public bool IsGroupMember(UUID groupID) { return m_groupPowers.ContainsKey(groupID); } + public int PingTimeMS + { + get + { + if (UDPClient != null) + return UDPClient.PingTimeMS; + return 0; + } + } + /// /// Entity update queues /// @@ -461,6 +471,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP set { m_disableFacelights = value; } } + public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } @@ -1638,6 +1649,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pc.PingID.OldestUnacked = 0; OutPacket(pc, ThrottleOutPacketType.Unknown); + UDPClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); } public void SendKillObject(List localIDs) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index bd4e617da9..9cf65d79c6 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -163,6 +163,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_maxRTO = 60000; public bool m_deliverPackets = true; + public int m_lastStartpingTimeMS; + public int m_pingMS; + + public int PingTimeMS + { + get + { + if (m_pingMS < 20) + return 20; + if(m_pingMS > 2000) + return 2000; + return m_pingMS; + } + } + /// /// This is the percentage of the udp texture queue to add to the task queue since /// textures are now generally handled through http. @@ -225,6 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Initialize this to a sane value to prevent early disconnects TickLastPacketReceived = Environment.TickCount & Int32.MaxValue; + m_pingMS = (int)(3.0 * server.TickCountResolution); // so filter doesnt start at 0; } /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index fe79f870a9..910d7cf733 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -293,6 +293,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings protected bool m_sendPing; + private ExpiringCache> m_pendingCache = new ExpiringCache>(); /// @@ -369,16 +370,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Measure the resolution of Environment.TickCount TickCountResolution = 0f; - for (int i = 0; i < 5; i++) + for (int i = 0; i < 10; i++) { int start = Environment.TickCount; int now = start; while (now == start) now = Environment.TickCount; - TickCountResolution += (float)(now - start) * 0.2f; + TickCountResolution += (float)(now - start) * 0.1f; } - m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); TickCountResolution = (float)Math.Ceiling(TickCountResolution); + m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms"); #endregion Environment.TickCount Measurement @@ -386,6 +387,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP int sceneThrottleBps = 0; bool usePools = false; + + IConfig config = configSource.Configs["ClientStack.LindenUDP"]; if (config != null) { @@ -1128,6 +1131,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP pc.PingID.OldestUnacked = 0; SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null); + udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount(); } public void CompletePing(LLUDPClient udpClient, byte pingID) @@ -1567,7 +1571,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // We don't need to do anything else with ping checks StartPingCheckPacket startPing = (StartPingCheckPacket)packet; CompletePing(udpClient, startPing.PingID.PingID); - + if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000) { udpClient.SendPacketStats(); @@ -1577,7 +1581,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else if (packet.Type == PacketType.CompletePingCheck) { - // We don't currently track client ping times + int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS); + int c = udpClient.m_pingMS; + c = 900 * c + 100 * t; + c /= 1000; + udpClient.m_pingMS = c; return; } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 373ed418fd..f35ea92caf 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -58,6 +58,8 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public ISceneAgent SceneAgent { get; set; } + public int PingTimeMS { get { return 0; } } + private string m_username; private string m_nick; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index c88ccc5e86..7002d75869 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -81,6 +81,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC get { return m_scene; } } + public int PingTimeMS { get { return 0; } } + public UUID OwnerID { get { return m_ownerID; } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 52e0134aff..f3eaed3a2a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -379,6 +379,8 @@ namespace OpenSim.Tests.Common.Mock get { return FirstName + " " + LastName; } } + public int PingTimeMS { get { return 0; } } + public bool IsActive { get { return true; }