12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- using System;
- using System.Collections.Generic;
- namespace Mirror
- {
- // a server's connection TO a LocalClient.
- // sending messages on this connection causes the client's handler function to be invoked directly
- 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";
- internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
- {
- // 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();
- writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
- connectionToServer.queue.Enqueue(writer);
- }
- // true because local connections never timeout
- internal override bool IsAlive(float timeout) => true;
- // 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
- // (might be client or host mode here)
- isReady = false;
- RemoveFromObservingsObservers();
- }
- /// <summary>Disconnects this connection.</summary>
- public override void Disconnect()
- {
- DisconnectInternal();
- connectionToServer.DisconnectInternal();
- }
- }
- }
|