Weird Behaviour with FastBufferReader

Hi!

I was trying out the custom messaging system where I used the FastBufferWriter/Reader to send a json-formatted string to the client.

The writing Side looks like this:

SendPlayerInformationResult()
{
       string json = JsonUtility.ToJson(playerInformation);
        byte[] bytes = Encoding.ASCII.GetBytes(json);

        Debug.Log("Try to send ("+ bytes.Length + "): "  + json);

        using var writer = new FastBufferWriter(sizeof(byte) * bytes.Length, Unity.Collections.Allocator.Temp);
      
      
        writer.WriteBytesSafe(bytes);
        NetworkManager
        .Singleton
        .CustomMessagingManager
.SendNamedMessageToAll(nameof(S2CNewPlayerInformationResult_CustomMessage), writer);
}

The Reading side looks like this:

S2CNewPlayerInformationResult_CustomMessage(ulong clientId, FastBufferReader r)
{     
        byte[] bytes = new byte[r.Length - 8 ];
        r.ReadBytesSafe(ref bytes, r.Length - 8);

        Debug.Log(r.Length);

        string json = Encoding.ASCII.GetString(bytes);
}

Now my question:
If you check the Reading Side you’ll see that I wrote “r.ReadBytesSafe(ref bytes, r.Length - 8);”
I did this because for some reason the FastBufferReader adds an additonal length of 8 to the actual string defined in the writing side.

Respectively when I send data with 100 characters, the reading side will have 108. If I do not remove those addtional 8 I will get an Overflow Exception. If I remove them then it works as it should.

Is there a reason behind that behaviour or just buggy or am I doing something completely wrong? :smile:.

Thanks for your replies! If something is unclear, let me know. Thank you!

When you write something variable size like a string you can’t rely on the length of the FastBufferReader because Netcode for GameObjects writes other meta information into that reader. Instead first write the length of the string into the writer and then on the receiving side read the length and after that read that many bytes.

Hi Luke!

Thanks for the fast reply.

What if you don’t know beforehand how long the string is going to be? For example sending some information only the server knows, but clients need to get informed about that.

On such a case is it better to define a fixed length for the buffer?

Would be great to update the documentation on this, as no where it explains how FastBufferReader and Writer are structured, I was just trying to copy a FastBufferReader into a FastBufferWriter and it’s really unclear how to do this.

This code seems to work:

reader.Seek(0); //Reset reader
reader.ReadValueSafe(out ulong hash); //Read header
byte[] bytes = new byte[reader.Length - 8]; //Header is ulong (8 bytes)
reader.ReadBytesSafe(ref bytes, reader.Length - 8); //Header is ulong (8 bytes)
FastBufferWriter writer = new FastBufferWriter(bytes.Length, Allocator.Temp);
writer.WriteBytesSafe(bytes, bytes.Length);

But this doesn’t, even though in theory it’s supposed to be the same

reader.Seek(0); //Reset reader
byte[] bytes = new byte[reader.Length - 8]; //Header is ulong (8 bytes)
reader.ReadBytesSafe(ref bytes, reader.Length - 8, 8); //Header is ulong (8 bytes), offset is also 8 to skip header
FastBufferWriter writer = new FastBufferWriter(bytes.Length, Allocator.Temp);
writer.WriteBytesSafe(bytes, bytes.Length);

So there is something unclear about how these work. Would be really good to have some doc on this.

Is the header for readerbuffer always a ulong ?

i want use easy API to send custom messsage ……

i dont know how to use fastBuffferwrite and reader …… ,how it work……

i hope like this

A a = new A();
FastBufferWriter bw;
bw.WriteValue(a);

manager.CustomMessagingManager.SendNamedMessage(“CustomMessaging”, NetworkManager.ServerClientId, bw, NetworkDelivery.Reliable);

[System.Serializable]
public class A
{
public float s = 23;

public string bb1 = “123asdfasdfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”;
public string bb2 = “23445”;

public string bb3 = “ertwer”;

public string bb4 = “tyru5”;

}

Net code is too young

Perhaps the API is not concise enough,

Or examples without an introduction,

Or maybe I’m not smart enough,

For some examples or issues, Google cannot help me

A lowly programmer from China

Hi @wechat_os_Qy0xkipWLGYk6K41qQOqJGO8s , have you tried using RPCs instead?

I made a free asset to help get started with Netcode. Many people told me this asset really helped them because i created a lot of premade functions and examples to help with stuff that aren’t clear.

https://assetstore.unity.com/packages/tools/network/netcode-plus-multiplayer-networking-and-demos-248538

sometime
i want to send custome message to client or server

like login or register send some data to server or ger some data form server
not rpc
rpc can send single id to client data

i think login custome message Better than RPC

I believe net code that potential is not just about synchronizing with multiple people

For example, chatting, logging in, calling

Thank you. I’ll go see it later

For these types of things you need to use Game Services, not multiplayer frameworks. NGO is a multiplayer framework. Unity Game Services are what you’re looking for :smile: