Skip to content

Commit ccbf652

Browse files
Feature/initial relay utp remove relay sdk calls (#1032)
* DST-528: Extracted Relay SDK calls out of UTP adapter for MLAPI; it now accepts a variable passed in via a setter method. Also updated the sample test project included to illustrate these changes. * DST-528: Made some changes that address feedback comments; mainly restructured the manner that code external to UTPTransport passes in the requisite relay server data so that external code doesn't need to know about the internal data structures that UTPTransport uses. * DST-528: Removing minor changes that were erroneously left in when taking other approaches.
1 parent 6322bbb commit ccbf652

File tree

14 files changed

+410
-217
lines changed

14 files changed

+410
-217
lines changed

com.unity.multiplayer.transport.utp/Runtime/UTPTransport.cs

Lines changed: 86 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,6 @@
44
using System.Threading.Tasks;
55
using Unity.Networking.Transport;
66
using Unity.Networking.Transport.Relay;
7-
#if ENABLE_RELAY_SERVICE
8-
using Unity.Services.Relay;
9-
using Unity.Services.Relay.Allocations;
10-
using Unity.Services.Relay.Models;
11-
using Unity.Services.Core;
12-
#endif
137

148
using MLAPI.Transports.Tasks;
159
using UnityEngine;
@@ -42,14 +36,11 @@ private enum State
4236
[SerializeField] private int m_MessageBufferSize = MaximumMessageLength;
4337
[SerializeField] private string m_ServerAddress = "127.0.0.1";
4438
[SerializeField] private ushort m_ServerPort = 7777;
45-
[SerializeField] private int m_RelayMaxPlayers = 10;
46-
[SerializeField] private string m_RelayServer = "https://relay-allocations.cloud.unity3d.com";
4739

4840
private State m_State = State.Disconnected;
4941
private NetworkDriver m_Driver;
5042
private List<INetworkParameter> m_NetworkParameters;
5143
private byte[] m_MessageBuffer;
52-
private string m_RelayJoinCode;
5344
private ulong m_ServerClientId;
5445

5546
private NetworkPipeline m_UnreliableSequencedPipeline;
@@ -58,16 +49,23 @@ private enum State
5849

5950
public override ulong ServerClientId => m_ServerClientId;
6051

61-
public string RelayJoinCode => m_RelayJoinCode;
62-
6352
public ProtocolType Protocol => m_ProtocolType;
6453

54+
private RelayServerData m_RelayServerData;
55+
56+
private static readonly RelayServerData k_DefaultRelayServerData = default(RelayServerData);
57+
private static RelayServerData DefaultRelayServerData => k_DefaultRelayServerData;
58+
6559
private void InitDriver()
6660
{
6761
if (m_NetworkParameters.Count > 0)
62+
{
6863
m_Driver = NetworkDriver.Create(m_NetworkParameters.ToArray());
64+
}
6965
else
66+
{
7067
m_Driver = NetworkDriver.Create();
68+
}
7169

7270
m_UnreliableSequencedPipeline = m_Driver.CreatePipeline(typeof(UnreliableSequencedPipelineStage));
7371
m_ReliableSequencedPipeline = m_Driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));
@@ -79,39 +77,8 @@ private void InitDriver()
7977
private void DisposeDriver()
8078
{
8179
if (m_Driver.IsCreated)
82-
m_Driver.Dispose();
83-
}
84-
85-
private static RelayAllocationId ConvertFromAllocationIdBytes(byte[] allocationIdBytes)
86-
{
87-
unsafe
88-
{
89-
fixed (byte* ptr = allocationIdBytes)
90-
{
91-
return RelayAllocationId.FromBytePointer(ptr, allocationIdBytes.Length);
92-
}
93-
}
94-
}
95-
96-
private static RelayHMACKey ConvertFromHMAC(byte[] hmac)
97-
{
98-
unsafe
99-
{
100-
fixed (byte* ptr = hmac)
101-
{
102-
return RelayHMACKey.FromBytePointer(ptr, RelayHMACKey.k_Length);
103-
}
104-
}
105-
}
106-
107-
private static RelayConnectionData ConvertConnectionData(byte[] connectionData)
108-
{
109-
unsafe
11080
{
111-
fixed (byte* ptr = connectionData)
112-
{
113-
return RelayConnectionData.FromBytePointer(ptr, RelayConnectionData.k_Length);
114-
}
81+
m_Driver.Dispose();
11582
}
11683
}
11784

@@ -134,7 +101,9 @@ private NetworkPipeline SelectSendPipeline(NetworkChannel channel, int size)
134101
case NetworkDelivery.ReliableFragmentedSequenced:
135102
// No need to send on the fragmented pipeline if data is smaller than MTU.
136103
if (size < NetworkParameterConstants.MTU)
104+
{
137105
return m_ReliableSequencedPipeline;
106+
}
138107

139108
return m_ReliableSequencedFragmentedPipeline;
140109

@@ -150,43 +119,15 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
150119

151120
if (m_ProtocolType == ProtocolType.RelayUnityTransport)
152121
{
153-
#if !ENABLE_RELAY_SERVICE
154-
Debug.LogError("You must have Relay SDK installed via the UDash in order to use the relay transport");
155-
yield return null;
156-
#else
157-
var joinTask = RelayService.AllocationsApiClient.JoinRelayAsync(new JoinRelayRequest(new JoinRequest(m_RelayJoinCode)));
158-
159-
while(!joinTask.IsCompleted)
160-
yield return null;
161-
162-
if (joinTask.IsFaulted)
122+
//This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
123+
//reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
124+
if(m_RelayServerData.Equals(DefaultRelayServerData))
163125
{
164-
Debug.LogError("Join Relay request failed");
165-
task.IsDone = true;
166-
task.Success = false;
126+
Debug.LogError("You must set the RelayServerData property to something different from the default value before calling StartRelayServer.");
167127
yield break;
168128
}
169129

170-
var allocation = joinTask.Result.Result.Data.Allocation;
171-
172-
serverEndpoint = NetworkEndPoint.Parse(allocation.RelayServer.IpV4, (ushort)allocation.RelayServer.Port);
173-
174-
var allocationId = ConvertFromAllocationIdBytes(allocation.AllocationIdBytes);
175-
176-
var connectionData = ConvertConnectionData(allocation.ConnectionData);
177-
var hostConnectionData = ConvertConnectionData(allocation.HostConnectionData);
178-
var key = ConvertFromHMAC(allocation.Key);
179-
180-
Debug.Log($"client: {allocation.ConnectionData[0]} {allocation.ConnectionData[1]}");
181-
Debug.Log($"host: {allocation.HostConnectionData[0]} {allocation.HostConnectionData[1]}");
182-
183-
Debug.Log($"client: {allocation.AllocationId}");
184-
185-
var relayServerData = new RelayServerData(ref serverEndpoint, 0, ref allocationId, ref connectionData, ref hostConnectionData, ref key);
186-
relayServerData.ComputeNewNonce();
187-
188-
m_NetworkParameters.Add(new RelayNetworkParameter{ ServerData = relayServerData });
189-
#endif
130+
m_NetworkParameters.Add(new RelayNetworkParameter{ ServerData = m_RelayServerData });
190131
}
191132
else
192133
{
@@ -223,8 +164,6 @@ private IEnumerator ClientBindAndConnect(SocketTask task)
223164
{
224165
Debug.LogError("Client failed to connect to server");
225166
}
226-
227-
228167
}
229168

230169
task.IsDone = true;
@@ -256,69 +195,80 @@ private IEnumerator ServerBindAndListen(SocketTask task, NetworkEndPoint endPoin
256195
{
257196
Debug.LogError("Server failed to listen");
258197
}
259-
260-
261198
}
262199

263200
task.IsDone = true;
264201
}
265202

266-
267-
private IEnumerator StartRelayServer(SocketTask task)
203+
private static RelayAllocationId ConvertFromAllocationIdBytes(byte[] allocationIdBytes)
268204
{
269-
#if !ENABLE_RELAY_SERVICE
270-
Debug.LogError("You must have Relay SDK installed via the UDash in order to use the relay transport");
271-
yield return null;
272-
#else
273-
var allocationTask = RelayService.AllocationsApiClient.CreateAllocationAsync(new CreateAllocationRequest(new AllocationRequest(m_RelayMaxPlayers)));
274-
275-
while(!allocationTask.IsCompleted)
205+
unsafe
276206
{
277-
yield return null;
207+
fixed (byte* ptr = allocationIdBytes)
208+
{
209+
return RelayAllocationId.FromBytePointer(ptr, allocationIdBytes.Length);
210+
}
278211
}
212+
}
279213

280-
if (allocationTask.IsFaulted)
214+
private static RelayHMACKey ConvertFromHMAC(byte[] hmac)
215+
{
216+
unsafe
281217
{
282-
Debug.LogError("Create allocation request failed");
283-
task.IsDone = true;
284-
task.Success = false;
285-
yield break;
218+
fixed (byte* ptr = hmac)
219+
{
220+
return RelayHMACKey.FromBytePointer(ptr, RelayHMACKey.k_Length);
221+
}
286222
}
223+
}
287224

288-
var allocation = allocationTask.Result.Result.Data.Allocation;
289-
290-
var joinCodeTask = RelayService.AllocationsApiClient.CreateJoincodeAsync(new CreateJoincodeRequest(new JoinCodeRequest(allocation.AllocationId)));
225+
private static RelayConnectionData ConvertConnectionData(byte[] connectionData)
226+
{
227+
unsafe
228+
{
229+
fixed (byte* ptr = connectionData)
230+
{
231+
return RelayConnectionData.FromBytePointer(ptr, RelayConnectionData.k_Length);
232+
}
233+
}
234+
}
291235

292-
while(!joinCodeTask.IsCompleted)
236+
public void SetRelayServerData(string ipv4address, ushort port, byte[] allocationIdBytes, byte[] keyBytes, byte[] connectionDataBytes, byte[] hostConnectionDataBytes = null)
237+
{
238+
RelayConnectionData hostConnectionData;
239+
240+
var serverEndpoint = NetworkEndPoint.Parse(ipv4address, port);
241+
var allocationId = ConvertFromAllocationIdBytes(allocationIdBytes);
242+
var key = ConvertFromHMAC(keyBytes);
243+
var connectionData = ConvertConnectionData(connectionDataBytes);
244+
245+
if (hostConnectionDataBytes != null)
246+
{
247+
hostConnectionData = ConvertConnectionData(hostConnectionDataBytes);
248+
}
249+
else
293250
{
294-
yield return null;
251+
hostConnectionData = connectionData;
295252
}
253+
m_RelayServerData = new RelayServerData(ref serverEndpoint, 0, ref allocationId, ref connectionData, ref hostConnectionData, ref key);
254+
m_RelayServerData.ComputeNewNonce();
255+
}
296256

297-
if (joinCodeTask.IsFaulted)
257+
private IEnumerator StartRelayServer(SocketTask task)
258+
{
259+
//This comparison is currently slow since RelayServerData does not implement a custom comparison operator that doesn't use
260+
//reflection, but this does not live in the context of a performance-critical loop, it runs once at initial connection time.
261+
if (m_RelayServerData.Equals(DefaultRelayServerData))
298262
{
299-
Debug.LogError("Create join code request failed");
300-
task.IsDone = true;
301-
task.Success = false;
263+
Debug.LogError("You must set the RelayServerData property to something different from the default value before calling StartRelayServer.");
302264
yield break;
303265
}
266+
else
267+
{
268+
m_NetworkParameters.Add(new RelayNetworkParameter { ServerData = m_RelayServerData });
304269

305-
m_RelayJoinCode = joinCodeTask.Result.Result.Data.JoinCode;
306-
307-
var serverEndpoint = NetworkEndPoint.Parse(allocation.RelayServer.IpV4, (ushort)allocation.RelayServer.Port);
308-
// Debug.Log($"Relay Server endpoint: {allocation.RelayServer.IpV4}:{(ushort)allocation.RelayServer.Port}");
309-
310-
var allocationId = ConvertFromAllocationIdBytes(allocation.AllocationIdBytes);
311-
var connectionData = ConvertConnectionData(allocation.ConnectionData);
312-
var key = ConvertFromHMAC(allocation.Key);
313-
314-
315-
var relayServerData = new RelayServerData(ref serverEndpoint, 0, ref allocationId, ref connectionData, ref connectionData, ref key);
316-
relayServerData.ComputeNewNonce();
317-
318-
m_NetworkParameters.Add(new RelayNetworkParameter{ ServerData = relayServerData });
319-
320-
yield return ServerBindAndListen(task, NetworkEndPoint.AnyIpv4);
321-
#endif
270+
yield return ServerBindAndListen(task, NetworkEndPoint.AnyIpv4);
271+
}
322272
}
323273

324274
private bool AcceptConnection()
@@ -396,8 +346,15 @@ private void Update()
396346
if (m_Driver.IsCreated)
397347
{
398348
m_Driver.ScheduleUpdate().Complete();
399-
while(AcceptConnection() && m_Driver.IsCreated);
400-
while(ProcessEvent() && m_Driver.IsCreated);
349+
while(AcceptConnection() && m_Driver.IsCreated)
350+
{
351+
;
352+
}
353+
354+
while (ProcessEvent() && m_Driver.IsCreated)
355+
{
356+
;
357+
}
401358
}
402359

403360
}
@@ -417,14 +374,6 @@ private static unsafe NetworkConnection ParseClientId(ulong mlapiConnectionId)
417374
return *(NetworkConnection*)&mlapiConnectionId;
418375
}
419376

420-
public void SetRelayJoinCode(string value)
421-
{
422-
if (m_State == State.Disconnected)
423-
{
424-
m_RelayJoinCode = value;
425-
}
426-
}
427-
428377
public override void DisconnectLocalClient()
429378
{
430379
Debug.Assert(m_State == State.Connected, "DisconnectLocalClient should be called on a connected client");
@@ -462,20 +411,13 @@ public override void Init()
462411

463412
m_NetworkParameters = new List<INetworkParameter>();
464413

465-
466414
// If we want to be able to actually handle messages MaximumMessageLength bytes in
467415
// size, we need to allow a bit more than that in FragmentationUtility since this needs
468416
// to account for headers and such. 128 bytes is plenty enough for such overhead.
469417
var maxFragmentationCapacity = MaximumMessageLength + 128;
470418
m_NetworkParameters.Add(new FragmentationUtility.Parameters(){PayloadCapacity = maxFragmentationCapacity});
471419

472420
m_MessageBuffer = new byte[m_MessageBufferSize];
473-
#if ENABLE_RELAY_SERVICE
474-
if (m_ProtocolType == ProtocolType.RelayUnityTransport) {
475-
Unity.Services.Relay.RelayService.Configuration.BasePath = m_RelayServer;
476-
UnityServices.Initialize();
477-
}
478-
#endif
479421
}
480422

481423
public override NetworkEvent PollEvent(out ulong clientId, out NetworkChannel networkChannel, out ArraySegment<byte> payload, out float receiveTime)
@@ -510,7 +452,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
510452
}
511453

512454
if (m_Driver.EndSend(writer) == size)
455+
{
513456
return;
457+
}
514458
}
515459

516460
Debug.LogError("Error sending the message");
@@ -519,7 +463,9 @@ public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChanne
519463
public override SocketTasks StartClient()
520464
{
521465
if (m_Driver.IsCreated)
466+
{
522467
return SocketTask.Fault.AsTasks();
468+
}
523469

524470
var task = SocketTask.Working;
525471
StartCoroutine(ClientBindAndConnect(task));
@@ -529,7 +475,9 @@ public override SocketTasks StartClient()
529475
public override SocketTasks StartServer()
530476
{
531477
if (m_Driver.IsCreated)
478+
{
532479
return SocketTask.Fault.AsTasks();
480+
}
533481

534482
var task = SocketTask.Working;
535483
switch (m_ProtocolType)

com.unity.multiplayer.transport.utp/Runtime/com.unity.multiplayer.transport.utp.asmdef

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66
"Unity.Jobs",
77
"Unity.Burst",
88
"Unity.Multiplayer.MLAPI.Runtime",
9-
"Unity.Networking.Transport",
10-
"Unity.Services.Relay",
11-
"Unity.Services.Core"
9+
"Unity.Networking.Transport"
1210
],
1311
"includePlatforms": [],
1412
"excludePlatforms": [],
@@ -17,12 +15,6 @@
1715
"precompiledReferences": [],
1816
"autoReferenced": true,
1917
"defineConstraints": [],
20-
"versionDefines": [
21-
{
22-
"name": "com.unity.services.relay",
23-
"expression": "0.0.1-preview.3",
24-
"define": "ENABLE_RELAY_SERVICE"
25-
}
26-
],
18+
"versionDefines": [],
2719
"noEngineReferences": false
2820
}

0 commit comments

Comments
 (0)