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> { }