Search Unity

Question Maximum data size in RPC

Discussion in 'Netcode for GameObjects' started by Balphagore, Feb 6, 2022.

  1. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    82
    What is the maximum size of data that can be sent in RPC? I created a class consisting of List<int>. I serialize it to a string, pass this string from the client as a parameter to RPC, and deserialize the string on the server. If this List consists of 0, then I can transfer 1024 values. 2048 is already throwing an error on the server side. If, instead of zeros, i fill in List from the loop with step 1 (0,1,2,3 etc), then an error is generated when 512 values are transferred.
    What are the restrictions?
    And how can i calculate whether a specific string will fit into RPC?
    And how does this restriction work when the server receives several RPCs at the same time?
    upload_2022-2-6_12-18-11.png
     
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    What error are you seeing?

    I was able to send an array of 10k ints, but for 20k I got the 'Writing past the end of the buffer' error. Changing transport settings didn't seem to make any difference.
     
  3. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    82
    I am getting this error on server:
    Code (CSharp):
    1. KeyNotFoundException: The given key was not present in the dictionary.
    2. System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <695d1cc93cca45069c528c15c9fdd749>:0)
    3. Unity.Netcode.NetworkManager.TransportIdToClientId (System.UInt64 transportId) (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1329)
    4. Unity.Netcode.NetworkManager.HandleRawTransportPoll (Unity.Netcode.NetworkEvent networkEvent, System.UInt64 clientId, System.ArraySegment`1[T] payload, System.Single receiveTime) (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1389)
    5. Unity.Netcode.NetworkManager.OnNetworkEarlyUpdate () (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1221)
    6. Unity.Netcode.NetworkManager.NetworkUpdate (Unity.Netcode.NetworkUpdateStage updateStage) (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1196)
    7. Unity.Netcode.NetworkUpdateLoop.RunNetworkUpdateStage (Unity.Netcode.NetworkUpdateStage updateStage) (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:149)
    8. Unity.Netcode.NetworkUpdateLoop+NetworkEarlyUpdate+<>c.<CreateLoopSystem>b__0_0 () (at D:/Software/Projects/Squad_War/RPC_Testing_Server/Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:172)
    I have this class on client and server NetworkObject:
    Code (CSharp):
    1.     [Serializable]
    2.     public class Test
    3.     {
    4.         public List<int> ints;
    5.         public Test(List<int> ints)
    6.         {
    7.             this.ints = ints;
    8.         }
    9.     }
    This RPC on client NetworkObject:
    Code (CSharp):
    1.     [ServerRpc]
    2.     private void TestServerRpc(string data)
    3.     {
    4.  
    5.     }
    This RPC on server NetworkObject:
    Code (CSharp):
    1.     [ServerRpc]
    2.     private void TestServerRpc(string data)
    3.     {
    4.         Test test = JsonUtility.FromJson<Test>(data);
    5.         Debug.Log(test.ints.Count);
    6.     }
    And on the client NetworkObject, I have a method that calls this code:
    Code (CSharp):
    1.         List<int> ints = new List<int>();
    2.         for (int i = 0; i < 2048; i++)
    3.         {
    4.             ints.Add(0);
    5.         }
    6.         Test test = new Test(ints);
    7.         string json = JsonUtility.ToJson(test);
    8.         TestServerRpc(json);
    As a result, when looping to 1024, everything works fine, and when looping to 2048, it gives the above error on the server.

    UPD:
    I raised the Message Buffer Size on NetworkManager from 5120 to 10240 and the error went away. Tried to send 4096 ints and it came back again. What are the limits for this size?
     
    Last edited: Feb 8, 2022
  4. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    Using your code in isolation I was able to send 5k ints, at 10k I got the writing past the end of the buffer again.

    Have you tried running pre.5 and the Unity transport, in case changing the Max Payload Size makes any difference.
     
  5. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    Last edited: Feb 8, 2022
  6. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    Ah yeah, in the editor under Unity Transport open up Connection Data and add the address to Server Listen Address. It can normally be left blank but it's bugged in pre.5.
     
    Last edited: Feb 8, 2022
  7. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    82
    Yes, if I quickly find and fix the problem myself, then I delete the comment)

    On topic, I seem to have switched to Unity Transport, and everything works. The error now occurs in the client:
    Code (CSharp):
    1. Payload of size 16439 larger than configured 'Max Payload Size' (6144).
    2. UnityEngine.Debug:LogError (object)
    3. Unity.Netcode.UnityTransport:Send (ulong,System.ArraySegment`1<byte>,Unity.Netcode.NetworkDelivery) (at Library/PackageCache/com.unity.netcode.adapter.utp@1.0.0-pre.5/Runtime/UnityTransport.cs:760)
    4. Unity.Netcode.NetworkManager/NetworkManagerMessageSender:Send (ulong,Unity.Netcode.NetworkDelivery,Unity.Netcode.FastBufferWriter) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:157)
    5. Unity.Netcode.MessagingSystem:ProcessSendQueues () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Messaging/MessagingSystem.cs:493)
    6. Unity.Netcode.NetworkManager:OnNetworkPostLateUpdate () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1265)
    7. Unity.Netcode.NetworkManager:NetworkUpdate (Unity.Netcode.NetworkUpdateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1202)
    8. Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage (Unity.Netcode.NetworkUpdateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:149)
    9. Unity.Netcode.NetworkUpdateLoop/NetworkPostLateUpdate/<>c:<CreateLoopSystem>b__0_0 () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:232)
    It's much more informative. Now I can experiment with the sizes. But I'm still wondering how the Server will behave when it accepts two RPCs of the maximum size at the same time. Will it queue a second RPC? Or will this RPC just disappear? I can't figure out yet how to simulate this situation to test.

    I also got a strange warning on the server and client when a PlayerObject spawns:
    Code (CSharp):
    1. [Netcode] Could not get NetworkObject for the NetworkBehaviour. Are you missing a NetworkObject component?
    2. UnityEngine.Debug:LogWarning (object)
    3. Unity.Netcode.NetworkLog:LogWarning (string) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Logging/NetworkLog.cs:18)
    4. Unity.Netcode.NetworkBehaviour:get_NetworkObject () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkBehaviour.cs:292)
    5. Unity.Netcode.NetworkBehaviour:get_NetworkBehaviourId () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkBehaviour.cs:315)
    6. Unity.Netcode.NetworkBehaviour:VariableUpdate (ulong) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkBehaviour.cs:494)
    7. Unity.Netcode.NetworkBehaviourUpdater:NetworkBehaviourUpdate (Unity.Netcode.NetworkManager) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkBehaviourUpdater.cs:36)
    8. Unity.Netcode.NetworkManager:OnNetworkManagerTick () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1285)
    9. Unity.Netcode.NetworkTickSystem:UpdateTick (double,double) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Timing/NetworkTickSystem.cs:96)
    10. Unity.Netcode.NetworkManager:OnNetworkPreUpdate () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1252)
    11. Unity.Netcode.NetworkManager:NetworkUpdate (Unity.Netcode.NetworkUpdateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkManager.cs:1199)
    12. Unity.Netcode.NetworkUpdateLoop:RunNetworkUpdateStage (Unity.Netcode.NetworkUpdateStage) (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:149)
    13. Unity.Netcode.NetworkUpdateLoop/NetworkPreUpdate/<>c:<CreateLoopSystem>b__0_0 () (at Library/PackageCache/com.unity.netcode.gameobjects@1.0.0-pre.5/Runtime/Core/NetworkUpdateLoop.cs:196)
    14.  
    With all this, there is only one NetworkBehaviour script on the scene and it hangs on the only player where there is a NetworkObject
     
  8. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    I don't think I can offer you any help on those, hopefully someone else will chime in.
     
    Balphagore likes this.
  9. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    82
    In any case, your advice helped me move forward. Thank you.
     
    cerestorm likes this.
  10. CosmicStud

    CosmicStud

    Joined:
    Jun 13, 2017
    Posts:
    55