diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs
index da3b797aea..210d7f660b 100644
--- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs
+++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs
@@ -16,8 +16,10 @@
using Unity.Networking.Transport.TLS;
using Unity.Networking.Transport.Utilities;
using UnityEngine;
-using NetcodeNetworkEvent = Unity.Netcode.NetworkEvent;
-using TransportNetworkEvent = Unity.Networking.Transport.NetworkEvent;
+
+using NetcodeEvent = Unity.Netcode.NetworkEvent;
+using TransportError = Unity.Networking.Transport.Error.StatusCode;
+using TransportEvent = Unity.Networking.Transport.NetworkEvent.Type;
namespace Unity.Netcode.Transports.UTP
{
@@ -42,56 +44,6 @@ void CreateDriver(
out NetworkPipeline reliableSequencedPipeline);
}
- ///
- /// Helper utility class to convert error codes to human readable error messages.
- ///
- public static class ErrorUtilities
- {
- private static readonly FixedString128Bytes k_NetworkSuccess = "Success";
- private static readonly FixedString128Bytes k_NetworkIdMismatch = "Invalid connection ID {0}.";
- private static readonly FixedString128Bytes k_NetworkVersionMismatch = "Connection ID is invalid. Likely caused by sending on stale connection {0}.";
- private static readonly FixedString128Bytes k_NetworkStateMismatch = "Connection state is invalid. Likely caused by sending on connection {0} which is stale or still connecting.";
- private static readonly FixedString128Bytes k_NetworkPacketOverflow = "Packet is too large to be allocated by the transport.";
- private static readonly FixedString128Bytes k_NetworkSendQueueFull = "Unable to queue packet in the transport. Likely caused by send queue size ('Max Send Queue Size') being too small.";
-
- ///
- /// Convert a UTP error code to human-readable error message.
- ///
- /// UTP error code.
- /// ID of the connection on which the error occurred.
- /// Human-readable error message.
- public static string ErrorToString(Networking.Transport.Error.StatusCode error, ulong connectionId)
- {
- return ErrorToString((int)error, connectionId);
- }
-
- internal static string ErrorToString(int error, ulong connectionId)
- {
- return ErrorToFixedString(error, connectionId).ToString();
- }
-
- internal static FixedString128Bytes ErrorToFixedString(int error, ulong connectionId)
- {
- switch ((Networking.Transport.Error.StatusCode)error)
- {
- case Networking.Transport.Error.StatusCode.Success:
- return k_NetworkSuccess;
- case Networking.Transport.Error.StatusCode.NetworkIdMismatch:
- return FixedString.Format(k_NetworkIdMismatch, connectionId);
- case Networking.Transport.Error.StatusCode.NetworkVersionMismatch:
- return FixedString.Format(k_NetworkVersionMismatch, connectionId);
- case Networking.Transport.Error.StatusCode.NetworkStateMismatch:
- return FixedString.Format(k_NetworkStateMismatch, connectionId);
- case Networking.Transport.Error.StatusCode.NetworkPacketOverflow:
- return k_NetworkPacketOverflow;
- case Networking.Transport.Error.StatusCode.NetworkSendQueueFull:
- return k_NetworkSendQueueFull;
- default:
- return FixedString.Format("Unknown error code {0}.", error);
- }
- }
- }
-
///
/// The Netcode for GameObjects NetworkTransport for UnityTransport.
/// Note: This is highly recommended to use over UNet.
@@ -114,13 +66,6 @@ public enum ProtocolType
RelayUnityTransport,
}
- private enum State
- {
- Disconnected,
- Listening,
- Connected,
- }
-
///
/// The default maximum (receive) packet queue size
///
@@ -421,17 +366,16 @@ private struct PacketLossCache
internal static event Action TransportInitialized;
internal static event Action TransportDisposed;
- internal NetworkDriver NetworkDriver => m_Driver;
///
- /// Provides access to the for this instance.
+ /// Provides access to the for this instance.
///
protected NetworkDriver m_Driver;
///
- /// Gets a reference to the .
+ /// Gets a reference to the .
///
- /// ref
+ /// ref
public ref NetworkDriver GetNetworkDriver()
{
return ref m_Driver;
@@ -455,7 +399,6 @@ public NetworkEndpoint GetLocalEndpoint()
private PacketLossCache m_PacketLossCache = new PacketLossCache();
- private State m_State = State.Disconnected;
private NetworkSettings m_NetworkSettings;
private ulong m_ServerClientId;
@@ -501,7 +444,7 @@ private void InitDriver()
out m_UnreliableSequencedFragmentedPipeline,
out m_ReliableSequencedPipeline);
- TransportInitialized?.Invoke(GetInstanceID(), NetworkDriver);
+ TransportInitialized?.Invoke(GetInstanceID(), m_Driver);
}
private void DisposeInternals()
@@ -583,8 +526,7 @@ private bool ClientBindAndConnect()
return false;
}
- var serverConnection = Connect(serverEndpoint);
- m_ServerClientId = ParseClientId(serverConnection);
+ Connect(serverEndpoint);
return true;
}
@@ -624,7 +566,6 @@ private bool ServerBindAndListen(NetworkEndpoint endPoint)
return false;
}
- m_State = State.Listening;
return true;
}
@@ -776,9 +717,9 @@ public void Execute()
while (!Queue.IsEmpty)
{
var result = Driver.BeginSend(pipeline, connection, out var writer);
- if (result != (int)Networking.Transport.Error.StatusCode.Success)
+ if (result != (int)TransportError.Success)
{
- Debug.LogError($"Error sending message: {ErrorUtilities.ErrorToFixedString(result, clientId)}");
+ Debug.LogError($"Send error on connection {clientId}: {ErrorUtilities.ErrorToFixedString(result)}");
return;
}
@@ -803,9 +744,9 @@ public void Execute()
// and we'll retry sending them later). Otherwise log the error and remove the
// message from the queue (we don't want to resend it again since we'll likely
// just get the same error again).
- if (result != (int)Networking.Transport.Error.StatusCode.NetworkSendQueueFull)
+ if (result != (int)TransportError.NetworkSendQueueFull)
{
- Debug.LogError($"Error sending the message: {ErrorUtilities.ErrorToFixedString(result, clientId)}");
+ Debug.LogError($"Send error on connection {clientId}: {ErrorUtilities.ErrorToFixedString(result)}");
Queue.Consume(written);
}
@@ -849,7 +790,7 @@ private bool AcceptConnection()
return false;
}
- InvokeOnTransportEvent(NetcodeNetworkEvent.Connect,
+ InvokeOnTransportEvent(NetcodeEvent.Connect,
ParseClientId(connection),
default,
m_RealTimeProvider.RealTimeSinceStartup);
@@ -887,7 +828,7 @@ private void ReceiveMessages(ulong clientId, NetworkPipeline pipeline, DataStrea
break;
}
- InvokeOnTransportEvent(NetcodeNetworkEvent.Data, clientId, message, m_RealTimeProvider.RealTimeSinceStartup);
+ InvokeOnTransportEvent(NetcodeEvent.Data, clientId, message, m_RealTimeProvider.RealTimeSinceStartup);
}
}
@@ -898,44 +839,38 @@ private bool ProcessEvent()
switch (eventType)
{
- case TransportNetworkEvent.Type.Connect:
+ case TransportEvent.Connect:
{
- InvokeOnTransportEvent(NetcodeNetworkEvent.Connect,
+ InvokeOnTransportEvent(NetcodeEvent.Connect,
clientId,
default,
m_RealTimeProvider.RealTimeSinceStartup);
- m_State = State.Connected;
+ m_ServerClientId = clientId;
return true;
}
- case TransportNetworkEvent.Type.Disconnect:
+ case TransportEvent.Disconnect:
{
- // Handle cases where we're a client receiving a Disconnect event. The
- // meaning of the event depends on our current state. If we were connected
- // then it means we got disconnected. If we were disconnected means that our
- // connection attempt has failed.
- if (m_State == State.Connected)
- {
- m_State = State.Disconnected;
- m_ServerClientId = default;
- }
- else if (m_State == State.Disconnected)
+ // If we're a client and had not yet set the server client ID, it means
+ // our connection to the server failed to be established. Any other case
+ // means a clean disconnect that doesn't require logging.
+ if (!m_Driver.Listening && m_ServerClientId == default)
{
Debug.LogError("Failed to connect to server.");
- m_ServerClientId = default;
}
+ m_ServerClientId = default;
m_ReliableReceiveQueues.Remove(clientId);
ClearSendQueuesForClientId(clientId);
- InvokeOnTransportEvent(NetcodeNetworkEvent.Disconnect,
+ InvokeOnTransportEvent(NetcodeEvent.Disconnect,
clientId,
default,
m_RealTimeProvider.RealTimeSinceStartup);
return true;
}
- case TransportNetworkEvent.Type.Data:
+ case TransportEvent.Data:
{
ReceiveMessages(clientId, pipeline, reader);
return true;
@@ -957,7 +892,7 @@ protected override void OnEarlyUpdate()
Debug.LogError("Transport failure! Relay allocation needs to be recreated, and NetworkManager restarted. " +
"Use NetworkManager.OnTransportFailure to be notified of such events programmatically.");
- InvokeOnTransportEvent(NetcodeNetworkEvent.TransportFailure, 0, default, m_RealTimeProvider.RealTimeSinceStartup);
+ InvokeOnTransportEvent(NetcodeEvent.TransportFailure, 0, default, m_RealTimeProvider.RealTimeSinceStartup);
return;
}
@@ -1180,13 +1115,13 @@ private void FlushSendQueuesForClientId(ulong clientId)
///
public override void DisconnectLocalClient()
{
- if (m_State == State.Connected)
+ if (m_ServerClientId != default)
{
FlushSendQueuesForClientId(m_ServerClientId);
if (m_Driver.Disconnect(ParseClientId(m_ServerClientId)) == 0)
{
- m_State = State.Disconnected;
+ m_ServerClientId = default;
m_ReliableReceiveQueues.Remove(m_ServerClientId);
ClearSendQueuesForClientId(m_ServerClientId);
@@ -1194,7 +1129,7 @@ public override void DisconnectLocalClient()
// If we successfully disconnect we dispatch a local disconnect message
// this how uNET and other transports worked and so this is just keeping with the old behavior
// should be also noted on the client this will call shutdown on the NetworkManager and the Transport
- InvokeOnTransportEvent(NetcodeNetworkEvent.Disconnect,
+ InvokeOnTransportEvent(NetcodeEvent.Disconnect,
m_ServerClientId,
default,
m_RealTimeProvider.RealTimeSinceStartup);
@@ -1209,14 +1144,14 @@ public override void DisconnectLocalClient()
public override void DisconnectRemoteClient(ulong clientId)
{
#if DEBUG
- if (m_State != State.Listening)
+ if (!m_Driver.IsCreated)
{
Debug.LogWarning($"{nameof(DisconnectRemoteClient)} should only be called on a listening server!");
return;
}
#endif
- if (m_State == State.Listening)
+ if (m_Driver.IsCreated)
{
FlushSendQueuesForClientId(clientId);
@@ -1331,12 +1266,12 @@ public override void Initialize(NetworkManager networkManager = null)
/// The incoming data payload
/// The time the event was received, as reported by m_RealTimeProvider.RealTimeSinceStartup.
/// Returns the event type
- public override NetcodeNetworkEvent PollEvent(out ulong clientId, out ArraySegment payload, out float receiveTime)
+ public override NetcodeEvent PollEvent(out ulong clientId, out ArraySegment payload, out float receiveTime)
{
clientId = default;
payload = default;
receiveTime = default;
- return NetcodeNetworkEvent.Nothing;
+ return NetcodeEvent.Nothing;
}
///
@@ -1404,7 +1339,7 @@ public override void Send(ulong clientId, ArraySegment payload, NetworkDel
DisconnectRemoteClient(clientId);
// DisconnectRemoteClient doesn't notify SDK of disconnection.
- InvokeOnTransportEvent(NetcodeNetworkEvent.Disconnect,
+ InvokeOnTransportEvent(NetcodeEvent.Disconnect,
clientId,
default(ArraySegment),
m_RealTimeProvider.RealTimeSinceStartup);
@@ -1520,10 +1455,9 @@ public override void Shutdown()
DisposeInternals();
m_ReliableReceiveQueues.Clear();
- m_State = State.Disconnected;
// We must reset this to zero because UTP actually re-uses clientIds if there is a clean disconnect
- m_ServerClientId = 0;
+ m_ServerClientId = default;
}
private void ConfigureSimulator()
@@ -1786,4 +1720,37 @@ public override int GetHashCode()
}
}
}
+
+ ///
+ /// Utility class to convert Unity Transport error codes to human-readable error messages.
+ ///
+ public static class ErrorUtilities
+ {
+ ///
+ /// Convert a Unity Transport error code to human-readable error message.
+ ///
+ /// Unity Transport error code.
+ /// ID of connection on which error occurred (unused).
+ /// Human-readable error message.
+ public static string ErrorToString(TransportError error, ulong connectionId)
+ {
+ return ErrorToFixedString((int)error).ToString();
+ }
+
+ internal static FixedString128Bytes ErrorToFixedString(int error)
+ {
+ switch ((TransportError)error)
+ {
+ case TransportError.NetworkVersionMismatch:
+ case TransportError.NetworkStateMismatch:
+ return "invalid connection state (likely stale/closed connection)";
+ case TransportError.NetworkPacketOverflow:
+ return "packet is too large for the transport (likely need to increase MTU)";
+ case TransportError.NetworkSendQueueFull:
+ return "send queue full (need to increase 'Max Send Queue Size' parameter)";
+ default:
+ return FixedString.Format("unexpected error code {0}", error);
+ }
+ }
+ }
}
diff --git a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs
index 87ffbdb418..bd9d9e937e 100644
--- a/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Editor/Transports/UnityTransportTests.cs
@@ -189,7 +189,7 @@ public void UnityTransport_EmptySecurityStringsShouldThrow([Values("", null)] st
networkManager.StartServer();
});
// Make sure StartServer failed
- Assert.False(transport.NetworkDriver.IsCreated);
+ Assert.False(transport.GetNetworkDriver().IsCreated);
Assert.False(networkManager.IsServer);
Assert.False(networkManager.IsListening);
}
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Metrics/PacketLossMetricsTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Metrics/PacketLossMetricsTests.cs
index 2956f48fda..1f9a35390f 100644
--- a/com.unity.netcode.gameobjects/Tests/Runtime/Metrics/PacketLossMetricsTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/Metrics/PacketLossMetricsTests.cs
@@ -64,9 +64,9 @@ public IEnumerator TrackPacketLossAsClient()
var clientNetworkManager = m_ClientNetworkManagers[0];
var clientTransport = (UnityTransport)clientNetworkManager.NetworkConfig.NetworkTransport;
- clientTransport.NetworkDriver.CurrentSettings.TryGet(out var parameters);
+ clientTransport.GetNetworkDriver().CurrentSettings.TryGet(out var parameters);
parameters.PacketDropPercentage = m_PacketLossRate;
- clientTransport.NetworkDriver.ModifySimulatorStageParameters(parameters);
+ clientTransport.GetNetworkDriver().ModifySimulatorStageParameters(parameters);
var waitForPacketLossMetric = new WaitForGaugeMetricValues((clientNetworkManager.NetworkMetrics as NetworkMetrics).Dispatcher,
NetworkMetricTypes.PacketLoss,
diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs
index ba68c4147f..03bd6c2c4c 100644
--- a/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs
+++ b/com.unity.netcode.gameobjects/Tests/Runtime/Transports/UnityTransportTests.cs
@@ -311,6 +311,8 @@ public IEnumerator DisconnectOnReliableSendQueueOverflow()
yield return WaitForNetworkEvent(NetworkEvent.Connect, m_Client1Events);
+ var serverClientId = m_Client1.ServerClientId;
+
m_Server.Shutdown();
var numSends = (maxSendQueueSize / 1024);
@@ -322,7 +324,7 @@ public IEnumerator DisconnectOnReliableSendQueueOverflow()
}
LogAssert.Expect(LogType.Error, "Couldn't add payload of size 1024 to reliable send queue. " +
- $"Closing connection {m_Client1.ServerClientId} as reliability guarantees can't be maintained.");
+ $"Closing connection {serverClientId} as reliability guarantees can't be maintained.");
Assert.AreEqual(2, m_Client1Events.Count);
Assert.AreEqual(NetworkEvent.Disconnect, m_Client1Events[1].Type);