Search Unity

Sending a massive package over RPC

Discussion in 'Multiplayer' started by gr33nl1nk, Apr 16, 2009.

  1. gr33nl1nk

    gr33nl1nk

    Joined:
    Dec 19, 2008
    Posts:
    92
    How do we send a massive package, say.. hundreds of floats data, over a single RPC call? because RPC can only send some certain types of parameter, and cant send arrays or an arbitrary object that contains the arrays.

    Is there anyway to package the data in a single object, and send it over the network in unity? I just need to send this data once before the game starts.
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    You would have to encode it into a string.
    There is string functionality that allows you to generate a byte[4] out of a float and vice versa.
    by putting those byte[4] all into the string you can send them through RPC

    there is no array type of object you can send
     
  3. cyb3rmaniak

    cyb3rmaniak

    Joined:
    Dec 10, 2007
    Posts:
    162
    It has some limitation, but you can also use XMLSerialize:
    Code (csharp):
    1. using UnityEngine;  
    2. using System.Collections.Generic;
    3.  
    4. using System.IO;
    5. using System.Text;
    6. using System.Xml.Serialization;
    7.  
    8. [System.Serializable]
    9. public class PlayerInfo
    10. {
    11.     public int nID = -1;
    12.     public int nCollabID = -1;
    13.     public string strName = "";
    14.     public bool bIsAdmin = false;
    15.     public Color cColor;
    16.     public int nNametagStyle = -1;
    17.     public string strTextureName = "";
    18.     public NetworkPlayer playerObject = new NetworkPlayer();
    19.     public int nAvatarID;
    20.     public Vector3 v3SpawnPosition;
    21.     public int nTeamID = -1;
    22.     public bool bAllInformationRecieved = false;
    23.     public string playerIpAddress = "0.0.0.0:0000";
    24.     public int nScore = 0;
    25.  
    26.     static XmlSerializer serializer = new XmlSerializer(typeof(PlayerInfo));
    27.     public string Serialize()
    28.     {
    29.         StringBuilder builder = new StringBuilder();  
    30.  
    31.         serializer.Serialize(
    32.          System.Xml.XmlWriter.Create(builder),
    33.          this);
    34.  
    35.         return builder.ToString();
    36.     }
    37.    
    38.     public static PlayerInfo Deserialize(string serializedData)
    39.     {
    40.        return serializer.Deserialize(new StringReader(serializedData)) as PlayerInfo;
    41.     }
    42.  
    43.     ...
    44. }
    45.  
    To send this entire class as an XML string you can use:
    Code (csharp):
    1. networkView.RPC("UpdatePlayers", RPCMode.Others, playersInfo.Serialize());
    And on the receiving end use:
    Code (csharp):
    1. // Client Side
    2. @RPC
    3. function UpdatePlayers(strAllPlayersSerialized: String)
    4. {
    5.     GuiDebug.Log("Recieved new players information!");
    6.    
    7.     // Deserealized the information and replace the local info with it
    8.     playersInfo = AllPlayersInfo.Deserialize(strAllPlayersSerialized);
    9. }
    10.  
    Just remember that RPC calls can be used to send upto 4096 bytes of information... XML Serialization is not exactly optimized for this, and you get some overhead because it's an XML string and not binary. You'll get exceptions at runtime if the class contains too much information.
     
  4. gr33nl1nk

    gr33nl1nk

    Joined:
    Dec 19, 2008
    Posts:
    92
    I realized that sending a string using RPC is limited to 4096 bytes, so definitely XML is not an option for me as I need to send data up to 8KB.

    Looks like I have to write a wrapper class which send bytes of data chunk by chunk, to send a package containing the marshalled data. but yeah.. i think the only option is to convert bytes of array into a string and send it via RPC.

    thanks for the answers!