- Home /
Sending bulk data via rpc
I'd like to send large chunks of bytes via RPC to my clients. This could be as much as 256k at a time. It's not constant, just at certain times.
It doesn't look like RPC has the ability to just send a byte[] array of values, so I've looked at converting bytes into a string.
Is there a better way to send this information to the clients, from my server? A key qualifier of "better" to me is ease of use. The RPC feature in Unity looks very easy to use, so I don't mind the string->byte->string conversion if it means avoiding a much more complicated way of sending the data.
I had that problem too. I've also used the serializing approach. If there's a better way that would be nice. In OnSerializeNetworkView you can send a custom mix of data but it would be nice to do that with RPCs. At least a byte array as parameter would be nice. I guess as string each letter is still serialized as a 16bit character, so that wouldn't be nice to reduce the packet size. For one-shot transfers i think serialize to string is the easiest way at the moment.
Answer by Julien-Lynge · Dec 09, 2011 at 09:56 PM
This is an old question, but it is absolutely possible to send byte arrays with RPC - it's just not a documented feature. I am currently using it to transmit images between networked Unity instances (after encoding to jpg or png), and it has worked fine for 10k up to 300k transfers, though note that RPC seems to buffer the calls, meaning that if you're sending data faster than the pipe can handle or the receiving function can process you'll get farther and farther behind as time goes on - you may want to include a timestamp header on your data transfers and throw away RPC calls when they get too stale.
Undocumented - so, would you $$anonymous$$d documenting how you did it here?
I can certainly provide a quick example. On the sending end:
byte[] bytesToSend = preTransferTexture.EncodeToPNG();
if (bytesToSend.Length > 0)
networkView.RPC("ReceiveWebcamPNG", RPC$$anonymous$$ode.Others, bytesToSend);
else
Debug.LogError("Bad length of bytes to send.");
and on the receiving end:
[RPC]
public void ReceiveWebcamPNG(byte[] bytes)
{
if (bytes.Length < 1)
{
Debug.LogError("Received bad byte count from network.");
return;
}
((Texture2D)renderer.shared$$anonymous$$aterial.mainTexture).LoadImage(bytes);
}
Some notes: On the sending end, if you are assigning color values to the preTransferTexture (say, pulling from a webcam), you don't have to 'Apply()' before creating the PNG byte array. On the receiving end, I include a sanity check for byte length; you could go a step further and include a checksum or expected length as a header, though in my testing on a few different machines I've never seen a case where data sent this way was corrupted - Unity may wrap such checks directly into the RPC calls, I don't know.
Final note: we started out sending PNGs and soon moved to JPG compression for speed reasons. There are plenty of libraries out there for encoding.
This answer is a life saver! When will Photon reference this or write their own?
I know this question is already answered and quite old but I just want to add that Unity "lately" added JPG encoding to Unity so there is no longer a need for an external library. cheers.
Your answer
Follow this Question
Related Questions
Really quick/easy question about RPCs 1 Answer
Send Texture Over Network 1 Answer
Network Question. Sending value from iPhone Client to Mac Server 1 Answer
Games with multiple maps 1 Answer