diff --git a/Source/Engine/Networking/Drivers/ENetDriver.cpp b/Source/Engine/Networking/Drivers/ENetDriver.cpp index 369c0d4b2..6fe25e723 100644 --- a/Source/Engine/Networking/Drivers/ENetDriver.cpp +++ b/Source/Engine/Networking/Drivers/ENetDriver.cpp @@ -7,9 +7,9 @@ #include "Engine/Networking/NetworkChannelType.h" #include "Engine/Networking/NetworkEvent.h" #include "Engine/Networking/NetworkPeer.h" +#include "Engine/Networking/NetworkStats.h" #include "Engine/Core/Log.h" #include "Engine/Core/Collections/Array.h" - #define ENET_IMPLEMENTATION #define _WINSOCK_DEPRECATED_NO_WARNINGS #include @@ -74,8 +74,8 @@ bool ENetDriver::Initialize(NetworkPeer* host, const NetworkConfig& config) void ENetDriver::Dispose() { if (_peer) - enet_peer_disconnect_now((ENetPeer*)_peer, 0); - enet_host_destroy((ENetHost*)_host); + enet_peer_disconnect_now(_peer, 0); + enet_host_destroy(_host); enet_deinitialize(); @@ -126,11 +126,11 @@ bool ENetDriver::Connect() } // Create ENet peer/connect to the server - _peer = enet_host_connect((ENetHost*)_host, &address, 1, 0); + _peer = enet_host_connect(_host, &address, 1, 0); if (_peer == nullptr) { LOG(Error, "Failed to create ENet host!"); - enet_host_destroy((ENetHost*)_host); + enet_host_destroy(_host); return false; } @@ -141,9 +141,8 @@ void ENetDriver::Disconnect() { if (_peer) { - enet_peer_disconnect_now((ENetPeer*)_peer, 0); + enet_peer_disconnect_now(_peer, 0); _peer = nullptr; - LOG(Info, "Disconnected"); } } @@ -154,7 +153,7 @@ void ENetDriver::Disconnect(const NetworkConnection& connection) ENetPeer* peer; if (_peerMap.TryGet(connectionId, peer)) { - enet_peer_disconnect_now((ENetPeer*)peer, 0); + enet_peer_disconnect_now(peer, 0); _peerMap.Remove(connectionId); } else @@ -166,7 +165,7 @@ void ENetDriver::Disconnect(const NetworkConnection& connection) bool ENetDriver::PopEvent(NetworkEvent* eventPtr) { ENetEvent event; - const int result = enet_host_service((ENetHost*)_host, &event, 0); + const int result = enet_host_service(_host, &event, 0); if (result < 0) LOG(Error, "Failed to check ENet events!"); if (result > 0) @@ -212,8 +211,8 @@ bool ENetDriver::PopEvent(NetworkEvent* eventPtr) void ENetDriver::SendMessage(const NetworkChannelType channelType, const NetworkMessage& message) { - ASSERT(IsServer() == false); - SendPacketToPeer((ENetPeer*)_peer, channelType, message); + ASSERT(!IsServer()); + SendPacketToPeer(_peer, channelType, message); } void ENetDriver::SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) @@ -238,3 +237,23 @@ void ENetDriver::SendMessage(const NetworkChannelType channelType, const Network } } } + +NetworkDriverStats ENetDriver::GetStats() +{ + return GetStats({ 0 }); +} + +NetworkDriverStats ENetDriver::GetStats(NetworkConnection target) +{ + NetworkDriverStats stats; + ENetPeer* peer = _peer; + if (!peer) + _peerMap.TryGet(target.ConnectionId, peer); + if (!peer && _host && _host->peerCount > 0) + peer = _host->peers; + if (peer) + { + stats.RTT = (float)peer->roundTripTime; + } + return stats; +} diff --git a/Source/Engine/Networking/Drivers/ENetDriver.h b/Source/Engine/Networking/Drivers/ENetDriver.h index ed944bd91..f8bdc407a 100644 --- a/Source/Engine/Networking/Drivers/ENetDriver.h +++ b/Source/Engine/Networking/Drivers/ENetDriver.h @@ -33,6 +33,8 @@ public: void SendMessage(NetworkChannelType channelType, const NetworkMessage& message) override; void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) override; void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array& targets) override; + NetworkDriverStats GetStats() override; + NetworkDriverStats GetStats(NetworkConnection target) override; private: bool IsServer() const @@ -43,7 +45,7 @@ private: private: NetworkConfig _config; NetworkPeer* _networkHost; - void* _host = nullptr; - void* _peer = nullptr; + struct _ENetHost* _host = nullptr; + struct _ENetPeer* _peer = nullptr; Dictionary _peerMap; }; diff --git a/Source/Engine/Networking/Drivers/NetworkLagDriver.cpp b/Source/Engine/Networking/Drivers/NetworkLagDriver.cpp index 41efebb67..32eaaad7e 100644 --- a/Source/Engine/Networking/Drivers/NetworkLagDriver.cpp +++ b/Source/Engine/Networking/Drivers/NetworkLagDriver.cpp @@ -5,6 +5,7 @@ #include "Engine/Core/Log.h" #include "Engine/Engine/Engine.h" #include "Engine/Engine/Time.h" +#include "Engine/Networking/NetworkStats.h" NetworkLagDriver::NetworkLagDriver(const SpawnParams& params) : ScriptingObject(params) @@ -147,6 +148,20 @@ void NetworkLagDriver::SendMessage(const NetworkChannelType channelType, const N msg.MessageData.Set(message.Buffer, message.Length); } +NetworkDriverStats NetworkLagDriver::GetStats() +{ + if (!_driver) + return NetworkDriverStats(); + return _driver->GetStats(); +} + +NetworkDriverStats NetworkLagDriver::GetStats(NetworkConnection target) +{ + if (!_driver) + return NetworkDriverStats(); + return _driver->GetStats(target); +} + void NetworkLagDriver::OnUpdate() { if (!_driver) diff --git a/Source/Engine/Networking/Drivers/NetworkLagDriver.h b/Source/Engine/Networking/Drivers/NetworkLagDriver.h index 56c1d81c1..7225c1c09 100644 --- a/Source/Engine/Networking/Drivers/NetworkLagDriver.h +++ b/Source/Engine/Networking/Drivers/NetworkLagDriver.h @@ -27,6 +27,7 @@ private: Array Targets; Array MessageData; // TODO: use message buffers cache (of size config.MessageSize) to reduce dynamic memory allocations }; + struct LagEvent { double Lag; @@ -71,6 +72,8 @@ public: void SendMessage(NetworkChannelType channelType, const NetworkMessage& message) override; void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, NetworkConnection target) override; void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array& targets) override; + NetworkDriverStats GetStats() override; + NetworkDriverStats GetStats(NetworkConnection target) override; private: void OnUpdate(); diff --git a/Source/Engine/Networking/INetworkDriver.h b/Source/Engine/Networking/INetworkDriver.h index 153225928..ddbb9f4e1 100644 --- a/Source/Engine/Networking/INetworkDriver.h +++ b/Source/Engine/Networking/INetworkDriver.h @@ -99,6 +99,16 @@ public: /// Can be used only by the server! API_FUNCTION() virtual void SendMessage(NetworkChannelType channelType, const NetworkMessage& message, const Array& targets) = 0; - // TODO: Stats API - // TODO: Simulation API + /// + /// Gets the network transport layer stats. + /// + /// Network transport statistics data for a given connection. + API_FUNCTION() virtual NetworkDriverStats GetStats() = 0; + + /// + /// Gets the network transport layer stats for a given connection. + /// + /// The client connection to retrieve statistics for. + /// Network transport statistics data for a given connection. + API_FUNCTION() virtual NetworkDriverStats GetStats(NetworkConnection target) = 0; }; diff --git a/Source/Engine/Networking/NetworkPeer.h b/Source/Engine/Networking/NetworkPeer.h index 5bb8f14ff..7a4c6c28c 100644 --- a/Source/Engine/Networking/NetworkPeer.h +++ b/Source/Engine/Networking/NetworkPeer.h @@ -13,23 +13,20 @@ /// API_CLASS(sealed, NoSpawn, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public ScriptingObject { - DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkPeer); + DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(NetworkPeer, ScriptingObject); + public: int HostId = -1; NetworkConfig Config; - INetworkDriver* NetworkDriver = nullptr; uint8* MessageBuffer = nullptr; Array MessagePool; public: /// - /// Initializes a new instance of the class. + /// Low-level network transport driver used by this peer. /// - NetworkPeer() - : ScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) - { - } + API_FIELD() INetworkDriver* NetworkDriver = nullptr; public: /// diff --git a/Source/Engine/Networking/NetworkStats.h b/Source/Engine/Networking/NetworkStats.h new file mode 100644 index 000000000..eaa1daedb --- /dev/null +++ b/Source/Engine/Networking/NetworkStats.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. + +#pragma once + +#include "Engine/Core/Compiler.h" +#include "Engine/Core/Config.h" + +/// +/// The network transport driver statistics container. Contains information about INetworkDriver usage and performance. +/// +API_STRUCT(Namespace="FlaxEngine.Networking") struct FLAXENGINE_API NetworkDriverStats +{ + DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkDriverStats); + + /// + /// The mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement. Also known as ping time. + /// + API_FIELD() float RTT = 0.0f; +}; + +template<> +struct TIsPODType +{ + enum { Value = true }; +}; diff --git a/Source/Engine/Networking/Types.h b/Source/Engine/Networking/Types.h index 23ee63d05..3ca5e6820 100644 --- a/Source/Engine/Networking/Types.h +++ b/Source/Engine/Networking/Types.h @@ -16,3 +16,4 @@ struct NetworkEvent; struct NetworkConnection; struct NetworkMessage; struct NetworkConfig; +struct NetworkDriverStats;