NetworkStatistics.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. using System;
  2. using UnityEngine;
  3. namespace Mirror
  4. {
  5. /// <summary>
  6. /// Shows Network messages and bytes sent and received per second.
  7. /// </summary>
  8. /// <remarks>
  9. /// <para>Add this component to the same object as Network Manager.</para>
  10. /// </remarks>
  11. [AddComponentMenu("Network/Network Statistics")]
  12. [DisallowMultipleComponent]
  13. [HelpURL("https://mirror-networking.gitbook.io/docs/components/network-statistics")]
  14. public class NetworkStatistics : MonoBehaviour
  15. {
  16. // update interval
  17. double intervalStartTime;
  18. // ---------------------------------------------------------------------
  19. // CLIENT (public fields for other components to grab statistics)
  20. // long bytes to support >2GB
  21. [HideInInspector] public int clientIntervalReceivedPackets;
  22. [HideInInspector] public long clientIntervalReceivedBytes;
  23. [HideInInspector] public int clientIntervalSentPackets;
  24. [HideInInspector] public long clientIntervalSentBytes;
  25. // results from last interval
  26. // long bytes to support >2GB
  27. [HideInInspector] public int clientReceivedPacketsPerSecond;
  28. [HideInInspector] public long clientReceivedBytesPerSecond;
  29. [HideInInspector] public int clientSentPacketsPerSecond;
  30. [HideInInspector] public long clientSentBytesPerSecond;
  31. // ---------------------------------------------------------------------
  32. // SERVER (public fields for other components to grab statistics)
  33. // capture interval
  34. // long bytes to support >2GB
  35. [HideInInspector] public int serverIntervalReceivedPackets;
  36. [HideInInspector] public long serverIntervalReceivedBytes;
  37. [HideInInspector] public int serverIntervalSentPackets;
  38. [HideInInspector] public long serverIntervalSentBytes;
  39. // results from last interval
  40. // long bytes to support >2GB
  41. [HideInInspector] public int serverReceivedPacketsPerSecond;
  42. [HideInInspector] public long serverReceivedBytesPerSecond;
  43. [HideInInspector] public int serverSentPacketsPerSecond;
  44. [HideInInspector] public long serverSentBytesPerSecond;
  45. // NetworkManager sets Transport.active in Awake().
  46. // so let's hook into it in Start().
  47. void Start()
  48. {
  49. // find available transport
  50. Transport transport = Transport.active;
  51. if (transport != null)
  52. {
  53. transport.OnClientDataReceived += OnClientReceive;
  54. transport.OnClientDataSent += OnClientSend;
  55. transport.OnServerDataReceived += OnServerReceive;
  56. transport.OnServerDataSent += OnServerSend;
  57. }
  58. else Debug.LogError($"NetworkStatistics: no available or active Transport found on this platform: {Application.platform}");
  59. }
  60. void OnDestroy()
  61. {
  62. // remove transport hooks
  63. Transport transport = Transport.active;
  64. if (transport != null)
  65. {
  66. transport.OnClientDataReceived -= OnClientReceive;
  67. transport.OnClientDataSent -= OnClientSend;
  68. transport.OnServerDataReceived -= OnServerReceive;
  69. transport.OnServerDataSent -= OnServerSend;
  70. }
  71. }
  72. void OnClientReceive(ArraySegment<byte> data, int channelId)
  73. {
  74. ++clientIntervalReceivedPackets;
  75. clientIntervalReceivedBytes += data.Count;
  76. }
  77. void OnClientSend(ArraySegment<byte> data, int channelId)
  78. {
  79. ++clientIntervalSentPackets;
  80. clientIntervalSentBytes += data.Count;
  81. }
  82. void OnServerReceive(int connectionId, ArraySegment<byte> data, int channelId)
  83. {
  84. ++serverIntervalReceivedPackets;
  85. serverIntervalReceivedBytes += data.Count;
  86. }
  87. void OnServerSend(int connectionId, ArraySegment<byte> data, int channelId)
  88. {
  89. ++serverIntervalSentPackets;
  90. serverIntervalSentBytes += data.Count;
  91. }
  92. void Update()
  93. {
  94. // calculate results every second
  95. if (NetworkTime.localTime >= intervalStartTime + 1)
  96. {
  97. if (NetworkClient.active) UpdateClient();
  98. if (NetworkServer.active) UpdateServer();
  99. intervalStartTime = NetworkTime.localTime;
  100. }
  101. }
  102. void UpdateClient()
  103. {
  104. clientReceivedPacketsPerSecond = clientIntervalReceivedPackets;
  105. clientReceivedBytesPerSecond = clientIntervalReceivedBytes;
  106. clientSentPacketsPerSecond = clientIntervalSentPackets;
  107. clientSentBytesPerSecond = clientIntervalSentBytes;
  108. clientIntervalReceivedPackets = 0;
  109. clientIntervalReceivedBytes = 0;
  110. clientIntervalSentPackets = 0;
  111. clientIntervalSentBytes = 0;
  112. }
  113. void UpdateServer()
  114. {
  115. serverReceivedPacketsPerSecond = serverIntervalReceivedPackets;
  116. serverReceivedBytesPerSecond = serverIntervalReceivedBytes;
  117. serverSentPacketsPerSecond = serverIntervalSentPackets;
  118. serverSentBytesPerSecond = serverIntervalSentBytes;
  119. serverIntervalReceivedPackets = 0;
  120. serverIntervalReceivedBytes = 0;
  121. serverIntervalSentPackets = 0;
  122. serverIntervalSentBytes = 0;
  123. }
  124. void OnGUI()
  125. {
  126. // only show if either server or client active
  127. if (NetworkClient.active || NetworkServer.active)
  128. {
  129. // create main GUI area
  130. // 120 is below NetworkManager HUD in all cases.
  131. GUILayout.BeginArea(new Rect(10, 120, 215, 300));
  132. // show client / server stats if active
  133. if (NetworkClient.active) OnClientGUI();
  134. if (NetworkServer.active) OnServerGUI();
  135. // end of GUI area
  136. GUILayout.EndArea();
  137. }
  138. }
  139. void OnClientGUI()
  140. {
  141. // background
  142. GUILayout.BeginVertical("Box");
  143. GUILayout.Label("<b>Client Statistics</b>");
  144. // sending ("msgs" instead of "packets" to fit larger numbers)
  145. GUILayout.Label($"Send: {clientSentPacketsPerSecond} msgs @ {Utils.PrettyBytes(clientSentBytesPerSecond)}/s");
  146. // receiving ("msgs" instead of "packets" to fit larger numbers)
  147. GUILayout.Label($"Recv: {clientReceivedPacketsPerSecond} msgs @ {Utils.PrettyBytes(clientReceivedBytesPerSecond)}/s");
  148. // end background
  149. GUILayout.EndVertical();
  150. }
  151. void OnServerGUI()
  152. {
  153. // background
  154. GUILayout.BeginVertical("Box");
  155. GUILayout.Label("<b>Server Statistics</b>");
  156. // sending ("msgs" instead of "packets" to fit larger numbers)
  157. GUILayout.Label($"Send: {serverSentPacketsPerSecond} msgs @ {Utils.PrettyBytes(serverSentBytesPerSecond)}/s");
  158. // receiving ("msgs" instead of "packets" to fit larger numbers)
  159. GUILayout.Label($"Recv: {serverReceivedPacketsPerSecond} msgs @ {Utils.PrettyBytes(serverReceivedBytesPerSecond)}/s");
  160. // end background
  161. GUILayout.EndVertical();
  162. }
  163. }
  164. }