slowpoker/Assets/Mirror/Components/NetworkStatistics.cs
2024-10-17 17:23:05 +03:00

195 lines
7.2 KiB
C#

using System;
using UnityEngine;
namespace Mirror
{
/// <summary>
/// Shows Network messages and bytes sent and received per second.
/// </summary>
/// <remarks>
/// <para>Add this component to the same object as Network Manager.</para>
/// </remarks>
[AddComponentMenu("Network/Network Statistics")]
[DisallowMultipleComponent]
[HelpURL("https://mirror-networking.gitbook.io/docs/components/network-statistics")]
public class NetworkStatistics : MonoBehaviour
{
// update interval
double intervalStartTime;
// ---------------------------------------------------------------------
// CLIENT (public fields for other components to grab statistics)
// long bytes to support >2GB
[HideInInspector] public int clientIntervalReceivedPackets;
[HideInInspector] public long clientIntervalReceivedBytes;
[HideInInspector] public int clientIntervalSentPackets;
[HideInInspector] public long clientIntervalSentBytes;
// results from last interval
// long bytes to support >2GB
[HideInInspector] public int clientReceivedPacketsPerSecond;
[HideInInspector] public long clientReceivedBytesPerSecond;
[HideInInspector] public int clientSentPacketsPerSecond;
[HideInInspector] public long clientSentBytesPerSecond;
// ---------------------------------------------------------------------
// SERVER (public fields for other components to grab statistics)
// capture interval
// long bytes to support >2GB
[HideInInspector] public int serverIntervalReceivedPackets;
[HideInInspector] public long serverIntervalReceivedBytes;
[HideInInspector] public int serverIntervalSentPackets;
[HideInInspector] public long serverIntervalSentBytes;
// results from last interval
// long bytes to support >2GB
[HideInInspector] public int serverReceivedPacketsPerSecond;
[HideInInspector] public long serverReceivedBytesPerSecond;
[HideInInspector] public int serverSentPacketsPerSecond;
[HideInInspector] public long serverSentBytesPerSecond;
// NetworkManager sets Transport.active in Awake().
// so let's hook into it in Start().
void Start()
{
// find available transport
Transport transport = Transport.active;
if (transport != null)
{
transport.OnClientDataReceived += OnClientReceive;
transport.OnClientDataSent += OnClientSend;
transport.OnServerDataReceived += OnServerReceive;
transport.OnServerDataSent += OnServerSend;
}
else Debug.LogError($"NetworkStatistics: no available or active Transport found on this platform: {Application.platform}");
}
void OnDestroy()
{
// remove transport hooks
Transport transport = Transport.active;
if (transport != null)
{
transport.OnClientDataReceived -= OnClientReceive;
transport.OnClientDataSent -= OnClientSend;
transport.OnServerDataReceived -= OnServerReceive;
transport.OnServerDataSent -= OnServerSend;
}
}
void OnClientReceive(ArraySegment<byte> data, int channelId)
{
++clientIntervalReceivedPackets;
clientIntervalReceivedBytes += data.Count;
}
void OnClientSend(ArraySegment<byte> data, int channelId)
{
++clientIntervalSentPackets;
clientIntervalSentBytes += data.Count;
}
void OnServerReceive(int connectionId, ArraySegment<byte> data, int channelId)
{
++serverIntervalReceivedPackets;
serverIntervalReceivedBytes += data.Count;
}
void OnServerSend(int connectionId, ArraySegment<byte> data, int channelId)
{
++serverIntervalSentPackets;
serverIntervalSentBytes += data.Count;
}
void Update()
{
// calculate results every second
if (NetworkTime.localTime >= intervalStartTime + 1)
{
if (NetworkClient.active) UpdateClient();
if (NetworkServer.active) UpdateServer();
intervalStartTime = NetworkTime.localTime;
}
}
void UpdateClient()
{
clientReceivedPacketsPerSecond = clientIntervalReceivedPackets;
clientReceivedBytesPerSecond = clientIntervalReceivedBytes;
clientSentPacketsPerSecond = clientIntervalSentPackets;
clientSentBytesPerSecond = clientIntervalSentBytes;
clientIntervalReceivedPackets = 0;
clientIntervalReceivedBytes = 0;
clientIntervalSentPackets = 0;
clientIntervalSentBytes = 0;
}
void UpdateServer()
{
serverReceivedPacketsPerSecond = serverIntervalReceivedPackets;
serverReceivedBytesPerSecond = serverIntervalReceivedBytes;
serverSentPacketsPerSecond = serverIntervalSentPackets;
serverSentBytesPerSecond = serverIntervalSentBytes;
serverIntervalReceivedPackets = 0;
serverIntervalReceivedBytes = 0;
serverIntervalSentPackets = 0;
serverIntervalSentBytes = 0;
}
void OnGUI()
{
// only show if either server or client active
if (NetworkClient.active || NetworkServer.active)
{
// create main GUI area
// 120 is below NetworkManager HUD in all cases.
GUILayout.BeginArea(new Rect(10, 120, 215, 300));
// show client / server stats if active
if (NetworkClient.active) OnClientGUI();
if (NetworkServer.active) OnServerGUI();
// end of GUI area
GUILayout.EndArea();
}
}
void OnClientGUI()
{
// background
GUILayout.BeginVertical("Box");
GUILayout.Label("<b>Client Statistics</b>");
// sending ("msgs" instead of "packets" to fit larger numbers)
GUILayout.Label($"Send: {clientSentPacketsPerSecond} msgs @ {Utils.PrettyBytes(clientSentBytesPerSecond)}/s");
// receiving ("msgs" instead of "packets" to fit larger numbers)
GUILayout.Label($"Recv: {clientReceivedPacketsPerSecond} msgs @ {Utils.PrettyBytes(clientReceivedBytesPerSecond)}/s");
// end background
GUILayout.EndVertical();
}
void OnServerGUI()
{
// background
GUILayout.BeginVertical("Box");
GUILayout.Label("<b>Server Statistics</b>");
// sending ("msgs" instead of "packets" to fit larger numbers)
GUILayout.Label($"Send: {serverSentPacketsPerSecond} msgs @ {Utils.PrettyBytes(serverSentBytesPerSecond)}/s");
// receiving ("msgs" instead of "packets" to fit larger numbers)
GUILayout.Label($"Recv: {serverReceivedPacketsPerSecond} msgs @ {Utils.PrettyBytes(serverReceivedBytesPerSecond)}/s");
// end background
GUILayout.EndVertical();
}
}
}