mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: fix: #3652 host [Command]s are now simulated over a message queue instead of invoking them directly (credits: Brian B.) (#3653)
* comment * fix: host [Command]s are now simulated over a message queue instead of invoking them directly (credits: Brian B.)
This commit is contained in:
parent
8ec937dfa6
commit
d4c0f20827
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Mirror
|
||||
{
|
||||
@ -8,6 +9,9 @@ public class LocalConnectionToClient : NetworkConnectionToClient
|
||||
{
|
||||
internal LocalConnectionToServer connectionToServer;
|
||||
|
||||
// packet queue
|
||||
internal readonly Queue<NetworkWriterPooled> queue = new Queue<NetworkWriterPooled>();
|
||||
|
||||
public LocalConnectionToClient() : base(LocalConnectionId) {}
|
||||
|
||||
public override string address => "localhost";
|
||||
@ -17,6 +21,7 @@ internal override void Send(ArraySegment<byte> segment, int channelId = Channels
|
||||
// instead of invoking it directly, we enqueue and process next update.
|
||||
// this way we can simulate a similar call flow as with remote clients.
|
||||
// the closer we get to simulating host as remote, the better!
|
||||
// both directions do this, so [Command] and [Rpc] behave the same way.
|
||||
|
||||
//Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}");
|
||||
NetworkWriterPooled writer = NetworkWriterPool.Get();
|
||||
@ -30,6 +35,35 @@ internal override void Send(ArraySegment<byte> segment, int channelId = Channels
|
||||
// don't ping host client in host mode
|
||||
protected override void UpdatePing() {}
|
||||
|
||||
internal override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// process internal messages so they are applied at the correct time
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
// call receive on queued writer's content, return to pool
|
||||
NetworkWriterPooled writer = queue.Dequeue();
|
||||
ArraySegment<byte> message = writer.ToArraySegment();
|
||||
|
||||
// OnTransportData assumes a proper batch with timestamp etc.
|
||||
// let's make a proper batch and pass it to OnTransportData.
|
||||
Batcher batcher = GetBatchForChannelId(Channels.Reliable);
|
||||
batcher.AddMessage(message, NetworkTime.localTime);
|
||||
|
||||
using (NetworkWriterPooled batchWriter = NetworkWriterPool.Get())
|
||||
{
|
||||
// make a batch with our local time (double precision)
|
||||
if (batcher.GetBatch(batchWriter))
|
||||
{
|
||||
NetworkServer.OnTransportData(connectionId, batchWriter.ToArraySegment(), Channels.Reliable);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkWriterPool.Return(writer);
|
||||
}
|
||||
}
|
||||
|
||||
internal void DisconnectInternal()
|
||||
{
|
||||
// set not ready and handle clientscene disconnect in any case
|
||||
|
@ -28,22 +28,15 @@ internal override void Send(ArraySegment<byte> segment, int channelId = Channels
|
||||
return;
|
||||
}
|
||||
|
||||
// OnTransportData assumes batching.
|
||||
// so let's make a batch with proper timestamp prefix.
|
||||
Batcher batcher = GetBatchForChannelId(channelId);
|
||||
batcher.AddMessage(segment, NetworkTime.localTime);
|
||||
// instead of invoking it directly, we enqueue and process next update.
|
||||
// this way we can simulate a similar call flow as with remote clients.
|
||||
// the closer we get to simulating host as remote, the better!
|
||||
// both directions do this, so [Command] and [Rpc] behave the same way.
|
||||
|
||||
// flush it to the server's OnTransportData immediately.
|
||||
// local connection to server always invokes immediately.
|
||||
using (NetworkWriterPooled writer = NetworkWriterPool.Get())
|
||||
{
|
||||
// make a batch with our local time (double precision)
|
||||
if (batcher.GetBatch(writer))
|
||||
{
|
||||
NetworkServer.OnTransportData(connectionId, writer.ToArraySegment(), channelId);
|
||||
}
|
||||
else Debug.LogError("Local connection failed to make batch. This should never happen.");
|
||||
}
|
||||
//Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}");
|
||||
NetworkWriterPooled writer = NetworkWriterPool.Get();
|
||||
writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
|
||||
connectionToClient.queue.Enqueue(writer);
|
||||
}
|
||||
|
||||
internal override void Update()
|
||||
|
Loading…
Reference in New Issue
Block a user