IRpcCommand with string data

Hello,

What is the right way to send a string (or byte array) using an RPC call. I tried using
NativeString64 (or fixed byte array) and it works but only if I disable the burst compiler. Otherwise the following error occurs:
System.InvalidOperationException: Received an invalid RPC
Thrown from job: Unity.NetCode.RpcSystem.RpcExecJob
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs → Burst → Enable Compilation) to inspect full exceptions & stacktraces.

Here’s my code:

public unsafe struct GoInGameRequest : IRpcCommand
{
    public int length;
    public NativeString64 data;

    PortableFunctionPointer<RpcExecutor.ExecuteDelegate> IRpcCommand.CompileExecute()
    {
        return new PortableFunctionPointer<RpcExecutor.ExecuteDelegate>(InvokeExecute);
    }

    [BurstCompile]
    private static void InvokeExecute(ref RpcExecutor.Parameters parameters)
    {
        RpcExecutor.ExecuteCreateRequestComponent<GoInGameRequest>(ref parameters);
    }

    void IRpcCommand.Deserialize(DataStreamReader reader, ref DataStreamReader.Context ctx)
    {
        length = reader.ReadInt(ref ctx);
        data = reader.ReadString(ref ctx);
    }

    void IRpcCommand.Serialize(DataStreamWriter writer)
    {
        writer.Write(length);
        writer.WriteString(data);
    }
}

[UpdateInGroup(typeof(ClientSimulationSystemGroup))]
public class GoInGameClientSystem : ComponentSystem
{
    protected override void OnCreate() { }

    protected override void OnUpdate()
    {
        Entities.WithNone<NetworkStreamInGame>().ForEach((Entity entity, ref NetworkIdComponent id) =>
        {
            PostUpdateCommands.AddComponent<NetworkStreamInGame>(entity);
            var request = PostUpdateCommands.CreateEntity();
            var goInGame = new GoInGameRequest();
            goInGame.length = 4;
            goInGame.data = "test";
            PostUpdateCommands.AddComponent(request, goInGame);
            PostUpdateCommands.AddComponent(request, new SendRpcCommandRequestComponent { TargetConnection = entity });
        });
    }
}

[UpdateInGroup(typeof(ServerSimulationSystemGroup))]
public class GoInGameServerSystem : ComponentSystem
{
    protected override void OnCreate() { }

    protected override void OnUpdate()
    {
        Entities.WithNone<SendRpcCommandRequestComponent>().ForEach((Entity entity, ref GoInGameRequest request, ref ReceiveRpcCommandRequestComponent source) =>
        {
            UnityEngine.Debug.Log(request.data);
            PostUpdateCommands.AddComponent<NetworkStreamInGame>(source.SourceConnection);
            PostUpdateCommands.DestroyEntity(entity);
        });
    }
}

public class GoInGameRequestSystem : RpcCommandRequestSystem<GoInGameRequest> { }

I think it is because you’re using managed code within the job “goInGame.data = “test”;” try place this outside of the burst job and only input the NativeString

Also I think you also need to use

[BurstCompile]
public unsafe struct GoInGameRequest : IRpcCommand

(edit)
As the error says, turn on full stack tracing to get a better explenation of the error, in which case I think you would solve it yourself : )

Thanks, that was the problem.

1 Like