|
| 1 | +using NetworkLibrary.Components.Statistics; |
| 2 | +using Protobuff.P2P; |
| 3 | +using RrlayServerTest; |
| 4 | +using System; |
| 5 | +using System.Collections.Concurrent; |
| 6 | +using System.Collections.Generic; |
| 7 | +using System.Diagnostics; |
| 8 | +using System.Diagnostics.CodeAnalysis; |
| 9 | +using System.Linq; |
| 10 | +using System.Net; |
| 11 | +using System.Numerics; |
| 12 | +using System.Runtime.CompilerServices; |
| 13 | +using System.Runtime.Intrinsics.Arm; |
| 14 | +using System.Text; |
| 15 | +using System.Text.Json; |
| 16 | +using System.Threading.Tasks; |
| 17 | + |
| 18 | +namespace RelayServer |
| 19 | +{ |
| 20 | + internal class HttpSimpleVisuals |
| 21 | + { |
| 22 | + HttpListener listener = new HttpListener(); |
| 23 | + private SecureProtoRelayServer? server; |
| 24 | + string p = "<html><body><body style=\"background-color:black;\"><font color=\"white\"><pre style=\"font-size: large; color: white;\">{0}</pre>"; |
| 25 | + string page = "<script>setTimeout(function(){ location.reload();},1000);</script></body></html>"; |
| 26 | + |
| 27 | + PerformanceCounter cpuCounter; |
| 28 | + PerformanceCounter ramCounter; |
| 29 | + |
| 30 | + PerformanceCounter total_cpu; //= new PerformanceCounter("Process", "% Processor Time", "_Total"); |
| 31 | + PerformanceCounter process_cpu; //= new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName); |
| 32 | + |
| 33 | + DateTime LastUpdate = DateTime.Now.AddSeconds(-2); |
| 34 | + private TcpStatistics TcpGeneralStats; |
| 35 | + private UdpStatistics udpGeneralStats; |
| 36 | + private ConcurrentDictionary<Guid, TcpStatistics> tctSessionStats; |
| 37 | + private ConcurrentDictionary<IPEndPoint, UdpStatistics> udpSessionStats; |
| 38 | + private GeneralStats generalStatJsonObject; |
| 39 | + |
| 40 | + public HttpSimpleVisuals(SecureProtoRelayServer s) |
| 41 | + { |
| 42 | + ArgumentNullException.ThrowIfNull(s); |
| 43 | + this.server = s; |
| 44 | + |
| 45 | + |
| 46 | + } |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | + public void BeginService() |
| 51 | + { |
| 52 | + //>netsh http add iplisten ipaddress=0.0.0.0:20012 |
| 53 | + //netsh http add urlacl url=http://*:20012/ user=everyone |
| 54 | + listener.Prefixes.Add("http://*:20012/"); |
| 55 | + listener.Prefixes.Add("http://*:20012/generalstats/"); |
| 56 | + |
| 57 | + listener.Start(); |
| 58 | + |
| 59 | + Task.Run(() => |
| 60 | + { |
| 61 | + while (true) |
| 62 | + { |
| 63 | + HttpListenerContext context = listener.GetContext(); |
| 64 | + HttpListenerRequest req = context.Request; |
| 65 | + if (req.HttpMethod == "GET") |
| 66 | + { |
| 67 | + if (req.RawUrl.Equals("/generalstats", StringComparison.OrdinalIgnoreCase)) |
| 68 | + { |
| 69 | + PrepareJsonResponse(context); |
| 70 | + } |
| 71 | + else if (req.RawUrl.Equals("/text", StringComparison.OrdinalIgnoreCase)) |
| 72 | + { |
| 73 | + PreparePrettyJsonPageResponse(context); |
| 74 | + } |
| 75 | + else |
| 76 | + { |
| 77 | + PrepareTextResponse(context); |
| 78 | + |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + } |
| 83 | + }); |
| 84 | + } |
| 85 | + |
| 86 | + #region Response |
| 87 | + private void PrepareTextResponse(HttpListenerContext context) |
| 88 | + { |
| 89 | + using HttpListenerResponse resp = context.Response; |
| 90 | + resp.Headers.Set("Content-Type", "text/html"); |
| 91 | + |
| 92 | + Update(); |
| 93 | + |
| 94 | + string data = |
| 95 | + "Session Count: " + tctSessionStats.Count + "\n" + |
| 96 | + "Cpu Usage: " + PerformanceStatistics.GetCpuUsage() + "\n" + |
| 97 | + "Memory Usage: " + PerformanceStatistics.GetMemoryUsage() + "\n" + |
| 98 | + TcpGeneralStats.ToString() + "\n\n" + |
| 99 | + udpGeneralStats.ToString(); |
| 100 | + |
| 101 | + var page_ = string.Format(p, data) + page; |
| 102 | + |
| 103 | + byte[] buffer = Encoding.UTF8.GetBytes(page_); |
| 104 | + resp.ContentLength64 = buffer.Length; |
| 105 | + |
| 106 | + using Stream ros = resp.OutputStream; |
| 107 | + ros.Write(buffer, 0, buffer.Length); |
| 108 | + } |
| 109 | + private void PrepareJsonResponse(HttpListenerContext context) |
| 110 | + { |
| 111 | + using HttpListenerResponse resp2 = context.Response; |
| 112 | + |
| 113 | + resp2.Headers.Set("Content-Type", "application/json; charset=utf-8"); |
| 114 | + resp2.Headers.Set("Access-Control-Allow-Origin", "*"); |
| 115 | + byte[] buffer_ = Encoding.UTF8.GetBytes(GetGeneralStatistics()); |
| 116 | + |
| 117 | + resp2.ContentLength64 = buffer_.Length; |
| 118 | + using Stream stream = resp2.OutputStream; |
| 119 | + stream.Write(buffer_, 0, buffer_.Length); |
| 120 | + } |
| 121 | + private void PreparePrettyJsonPageResponse(HttpListenerContext context) |
| 122 | + { |
| 123 | + using HttpListenerResponse resp2 = context.Response; |
| 124 | + |
| 125 | + resp2.Headers.Set("Content-Type", "text/html"); |
| 126 | + resp2.Headers.Set("Access-Control-Allow-Origin", "*"); |
| 127 | + byte[] buffer_ = Encoding.UTF8.GetBytes(Resources.StatisticsPage); |
| 128 | + |
| 129 | + resp2.ContentLength64 = buffer_.Length; |
| 130 | + using Stream stream = resp2.OutputStream; |
| 131 | + stream.Write(buffer_, 0, buffer_.Length); |
| 132 | + } |
| 133 | + |
| 134 | + #endregion |
| 135 | + |
| 136 | + public bool Update() |
| 137 | + { |
| 138 | + if ((DateTime.Now - LastUpdate).TotalMilliseconds < 900) |
| 139 | + return false; |
| 140 | + LastUpdate = DateTime.Now; |
| 141 | + server.GetTcpStatistics(out TcpGeneralStats, out tctSessionStats); |
| 142 | + server.GetUdpStatistics(out udpGeneralStats, out udpSessionStats); |
| 143 | + return true; |
| 144 | + } |
| 145 | + |
| 146 | + public string GetGeneralStatistics() |
| 147 | + { |
| 148 | + if (Update()) |
| 149 | + { |
| 150 | + generalStatJsonObject = new GeneralStats() |
| 151 | + { |
| 152 | + ResourceUsage = new ResourceUsage() |
| 153 | + { |
| 154 | + TotalSessions = tctSessionStats.Count.ToString(), |
| 155 | + CpuUsage = PerformanceStatistics.GetCpuUsage(), |
| 156 | + RamUsage = PerformanceStatistics.GetMemoryUsage() |
| 157 | + }, |
| 158 | + TcpGeneralStats = TcpGeneralStats.Stringify(), |
| 159 | + UdpGeneralStats = udpGeneralStats.Stringify() |
| 160 | + }; |
| 161 | + } |
| 162 | + |
| 163 | + return GetJson(generalStatJsonObject); |
| 164 | + |
| 165 | + } |
| 166 | + |
| 167 | + public string GetSessionStatistics() |
| 168 | + { |
| 169 | + Update(); |
| 170 | + |
| 171 | + var stats = new Dictionary<Guid, StatisticsJson>(); |
| 172 | + foreach (var item in tctSessionStats) |
| 173 | + { |
| 174 | + var stat = new StatisticsJson(); |
| 175 | + stat.TcpData = item.Value.Stringify(); |
| 176 | + stat.TcpEndpoint = new IpEndpointJsonData(server.GetIPEndPoint(item.Key)); |
| 177 | + stats[item.Key] = stat; |
| 178 | + |
| 179 | + } |
| 180 | + |
| 181 | + foreach (var item in udpSessionStats) |
| 182 | + { |
| 183 | + if (server.TryGetClientId(item.Key, out var clientId) |
| 184 | + && stats.ContainsKey(clientId)) |
| 185 | + { |
| 186 | + stats[clientId].UDpData = item.Value.Stringify(); |
| 187 | + stats[clientId].UdpEndpoint = new IpEndpointJsonData(item.Key); |
| 188 | + } |
| 189 | + } |
| 190 | + return GetJson(stats); |
| 191 | + } |
| 192 | + |
| 193 | + private string GetJson<T>(T data) where T : class |
| 194 | + { |
| 195 | + return JsonSerializer.Serialize<T>(data, new JsonSerializerOptions() { WriteIndented = true }); |
| 196 | + } |
| 197 | + |
| 198 | + public class StatisticsJson |
| 199 | + { |
| 200 | + public IpEndpointJsonData UdpEndpoint { get; set; } |
| 201 | + public IpEndpointJsonData TcpEndpoint { get; set; } |
| 202 | + |
| 203 | + public TcpStatisticsStringData TcpData { get; set; } |
| 204 | + |
| 205 | + public UdpStatisticsStringData UDpData { get; set; } |
| 206 | + |
| 207 | + } |
| 208 | + public class GeneralStats |
| 209 | + { |
| 210 | + public ResourceUsage ResourceUsage { get; set; } |
| 211 | + public TcpStatisticsStringData TcpGeneralStats { get; set; } |
| 212 | + public UdpStatisticsStringData UdpGeneralStats { get; set; } |
| 213 | + |
| 214 | + } |
| 215 | + |
| 216 | + public class ResourceUsage |
| 217 | + { |
| 218 | + public string TotalSessions { get; set; } |
| 219 | + public string CpuUsage { get; set; } |
| 220 | + public string RamUsage { get; set; } |
| 221 | + } |
| 222 | + |
| 223 | + public class IpEndpointJsonData |
| 224 | + { |
| 225 | + public string Ip { get; set; } |
| 226 | + public string Port { get; set; } |
| 227 | + public IpEndpointJsonData(IPEndPoint ep) |
| 228 | + { |
| 229 | + Ip = ep.Address.MapToIPv4().ToString(); |
| 230 | + Port = ep.Port.ToString(); |
| 231 | + } |
| 232 | + } |
| 233 | + |
| 234 | + |
| 235 | + |
| 236 | + } |
| 237 | +} |
0 commit comments