Skip to content

Commit 27e8409

Browse files
committed
Added RPC response timeout support
1 parent 8e3728a commit 27e8409

File tree

7 files changed

+92
-24
lines changed

7 files changed

+92
-24
lines changed

MLAPI/Data/RpcResponse.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@ public abstract class RpcResponseBase
2525
/// </summary>
2626
public ulong Id { get; internal set; }
2727
/// <summary>
28-
/// Whether or not a result has been received
28+
/// Whether or not the operation is done. This does not mean it was successful. Check IsSuccessful for that
29+
/// This will be true both when the operation was successful and when a timeout occured
2930
/// </summary>
3031
public bool IsDone { get; internal set; }
3132
/// <summary>
33+
/// Whether or not a valid result was received
34+
/// </summary>
35+
public bool IsSuccessful { get; set; }
36+
/// <summary>
3237
/// The clientId which the Request/Response was done wit
3338
/// </summary>
3439
public uint ClientId { get; internal set; }
40+
/// <summary>
41+
/// The amount of time to wait for the operation to complete
42+
/// </summary>
43+
public float Timeout { get; set; } = 10f;
3544
internal object Result { get; set; }
3645
internal Type Type { get; set; }
3746
}

MLAPI/MLAPI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
<Compile Include="NetworkingManagerComponents\Binary\SerializationHelper.cs" />
123123
<Compile Include="NetworkingManagerComponents\Binary\UIntFloat.cs" />
124124
<Compile Include="NetworkingManagerComponents\Core\LogHelper.cs" />
125+
<Compile Include="NetworkingManagerComponents\Core\ResponseMessageManager.cs" />
125126
<Compile Include="NetworkingManagerComponents\Cryptography\CryptographyHelper.cs" />
126127
<Compile Include="NetworkingManagerComponents\Cryptography\DiffieHellman.cs" />
127128
<Compile Include="NetworkingManagerComponents\Cryptography\EllipticCurve.cs" />

MLAPI/MonoBehaviours/Core/NetworkedBehaviour.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,7 @@ internal RpcResponse<T> SendServerRPCPerformanceResponse<T>(ulong hash, Stream m
890890
return null;
891891
}
892892

893-
ulong responseId = InternalMessageHandler.GenerateMessageId();
893+
ulong responseId = ResponseMessageManager.GenerateMessageId();
894894

895895
using (PooledBitStream stream = PooledBitStream.Get())
896896
{
@@ -913,6 +913,7 @@ internal RpcResponse<T> SendServerRPCPerformanceResponse<T>(ulong hash, Stream m
913913
{
914914
Id = responseId,
915915
IsDone = true,
916+
IsSuccessful = true,
916917
Result = result,
917918
Type = typeof(T),
918919
ClientId = NetworkingManager.Singleton.ServerClientId
@@ -924,11 +925,12 @@ internal RpcResponse<T> SendServerRPCPerformanceResponse<T>(ulong hash, Stream m
924925
{
925926
Id = responseId,
926927
IsDone = false,
928+
IsSuccessful = false,
927929
Type = typeof(T),
928930
ClientId = NetworkingManager.Singleton.ServerClientId
929931
};
930932

931-
InternalMessageHandler.Responses.Add(response.Id, response);
933+
ResponseMessageManager.Add(response.Id, response);
932934

933935
InternalMessageHandler.Send(NetworkingManager.Singleton.ServerClientId, MLAPIConstants.MLAPI_SERVER_RPC_REQUEST, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security);
934936

@@ -1070,7 +1072,7 @@ internal RpcResponse<T> SendClientRPCPerformanceResponse<T>(ulong hash, uint cli
10701072
return null;
10711073
}
10721074

1073-
ulong responseId = InternalMessageHandler.GenerateMessageId();
1075+
ulong responseId = ResponseMessageManager.GenerateMessageId();
10741076

10751077
using (PooledBitStream stream = PooledBitStream.Get())
10761078
{
@@ -1093,6 +1095,7 @@ internal RpcResponse<T> SendClientRPCPerformanceResponse<T>(ulong hash, uint cli
10931095
{
10941096
Id = responseId,
10951097
IsDone = true,
1098+
IsSuccessful = true,
10961099
Result = result,
10971100
Type = typeof(T),
10981101
ClientId = clientId
@@ -1104,11 +1107,12 @@ internal RpcResponse<T> SendClientRPCPerformanceResponse<T>(ulong hash, uint cli
11041107
{
11051108
Id = responseId,
11061109
IsDone = false,
1110+
IsSuccessful = false,
11071111
Type = typeof(T),
11081112
ClientId = clientId
11091113
};
11101114

1111-
InternalMessageHandler.Responses.Add(response.Id, response);
1115+
ResponseMessageManager.Add(response.Id, response);
11121116

11131117
InternalMessageHandler.Send(clientId, MLAPIConstants.MLAPI_CLIENT_RPC_REQUEST, string.IsNullOrEmpty(channel) ? "MLAPI_DEFAULT_MESSAGE" : channel, stream, security);
11141118

MLAPI/MonoBehaviours/Core/NetworkingManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ private object Init(bool server)
260260
ConnectedClientsList.Clear();
261261
messageBuffer = new byte[NetworkConfig.MessageBufferSize];
262262

263-
InternalMessageHandler.Responses.Clear();
263+
ResponseMessageManager.Clear();
264264
MessageManager.channels.Clear();
265265
MessageManager.reverseChannels.Clear();
266266
SpawnManager.SpawnedObjects.Clear();
@@ -758,6 +758,7 @@ private void Update()
758758
NetworkProfiler.StartTick(TickType.Event);
759759
eventOvershootCounter += ((NetworkTime - lastEventTickTime) - (1f / NetworkConfig.EventTickrate));
760760
LagCompensationManager.AddFrames();
761+
ResponseMessageManager.CheckTimeouts();
761762
lastEventTickTime = NetworkTime;
762763
NetworkProfiler.EndTick();
763764
}

MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.Receive.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -560,17 +560,17 @@ internal static void HandleServerRPCResponse(uint clientId, Stream stream, int c
560560
{
561561
ulong responseId = reader.ReadUInt64Packed();
562562

563-
if (InternalMessageHandler.Responses.ContainsKey(responseId))
563+
if (ResponseMessageManager.ContainsKey(responseId))
564564
{
565-
RpcResponseBase responseBase = InternalMessageHandler.Responses[responseId];
565+
RpcResponseBase responseBase = ResponseMessageManager.GetByKey(responseId);
566566

567567
if (responseBase.ClientId != clientId) return;
568568

569-
InternalMessageHandler.Responses.Remove(responseId);
569+
ResponseMessageManager.Remove(responseId);
570570

571-
responseBase.Result = reader.ReadObjectPacked(responseBase.Type);
572571
responseBase.IsDone = true;
573-
572+
responseBase.Result = reader.ReadObjectPacked(responseBase.Type);
573+
responseBase.IsSuccessful = true;
574574
}
575575
}
576576
}
@@ -631,16 +631,17 @@ internal static void HandleClientRPCResponse(uint clientId, Stream stream, int c
631631
{
632632
ulong responseId = reader.ReadUInt64Packed();
633633

634-
if (InternalMessageHandler.Responses.ContainsKey(responseId))
634+
if (ResponseMessageManager.ContainsKey(responseId))
635635
{
636-
RpcResponseBase responseBase = InternalMessageHandler.Responses[responseId];
636+
RpcResponseBase responseBase = ResponseMessageManager.GetByKey(responseId);
637637

638638
if (responseBase.ClientId != clientId) return;
639639

640-
InternalMessageHandler.Responses.Remove(responseId);
640+
ResponseMessageManager.Remove(responseId);
641641

642-
responseBase.Result = reader.ReadObjectPacked(responseBase.Type);
643642
responseBase.IsDone = true;
643+
responseBase.Result = reader.ReadObjectPacked(responseBase.Type);
644+
responseBase.IsSuccessful = true;
644645
}
645646
}
646647
}

MLAPI/NetworkingManagerComponents/Core/InternalMessageHandler.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,5 @@ namespace MLAPI.Internal
55
internal static partial class InternalMessageHandler
66
{
77
private static NetworkingManager netManager => NetworkingManager.Singleton;
8-
9-
internal static readonly Dictionary<ulong, RpcResponseBase> Responses = new Dictionary<ulong, RpcResponseBase>();
10-
11-
private static ulong messageIdCounter;
12-
13-
internal static ulong GenerateMessageId()
14-
{
15-
return messageIdCounter++;
16-
}
178
}
189
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System.Collections.Generic;
2+
using UnityEngine;
3+
4+
namespace MLAPI.Internal
5+
{
6+
internal static class ResponseMessageManager
7+
{
8+
private static readonly Dictionary<ulong, RpcResponseBase> pendingResponses = new Dictionary<ulong, RpcResponseBase>();
9+
private static readonly SortedList<ulong, float> responseAdded = new SortedList<ulong, float>();
10+
11+
private static ulong messageIdCounter;
12+
13+
internal static ulong GenerateMessageId()
14+
{
15+
return messageIdCounter++;
16+
}
17+
18+
internal static void CheckTimeouts()
19+
{
20+
while (responseAdded.Count > 0 && Time.time - responseAdded[0] > pendingResponses[responseAdded.Keys[0]].Timeout)
21+
{
22+
ulong key = responseAdded.Keys[0];
23+
24+
RpcResponseBase response = pendingResponses[key];
25+
response.IsDone = true;
26+
response.IsSuccessful = false;
27+
28+
responseAdded.Remove(key);
29+
pendingResponses.Remove(key);
30+
}
31+
}
32+
33+
internal static void Clear()
34+
{
35+
pendingResponses.Clear();
36+
responseAdded.Clear();
37+
}
38+
39+
internal static void Add(ulong key, RpcResponseBase value)
40+
{
41+
pendingResponses.Add(key, value);
42+
responseAdded.Add(key, Time.time);
43+
}
44+
45+
internal static void Remove(ulong key)
46+
{
47+
pendingResponses.Remove(key);
48+
responseAdded.Remove(key);
49+
}
50+
51+
internal static bool ContainsKey(ulong key)
52+
{
53+
return pendingResponses.ContainsKey(key);
54+
}
55+
56+
internal static RpcResponseBase GetByKey(ulong key)
57+
{
58+
return pendingResponses[key];
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)