LocalConnectionToClient.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System;
  2. using System.Collections.Generic;
  3. namespace Mirror
  4. {
  5. // a server's connection TO a LocalClient.
  6. // sending messages on this connection causes the client's handler function to be invoked directly
  7. public class LocalConnectionToClient : NetworkConnectionToClient
  8. {
  9. internal LocalConnectionToServer connectionToServer;
  10. // packet queue
  11. internal readonly Queue<NetworkWriterPooled> queue = new Queue<NetworkWriterPooled>();
  12. public LocalConnectionToClient() : base(LocalConnectionId) {}
  13. public override string address => "localhost";
  14. internal override void Send(ArraySegment<byte> segment, int channelId = Channels.Reliable)
  15. {
  16. // instead of invoking it directly, we enqueue and process next update.
  17. // this way we can simulate a similar call flow as with remote clients.
  18. // the closer we get to simulating host as remote, the better!
  19. // both directions do this, so [Command] and [Rpc] behave the same way.
  20. //Debug.Log($"Enqueue {BitConverter.ToString(segment.Array, segment.Offset, segment.Count)}");
  21. NetworkWriterPooled writer = NetworkWriterPool.Get();
  22. writer.WriteBytes(segment.Array, segment.Offset, segment.Count);
  23. connectionToServer.queue.Enqueue(writer);
  24. }
  25. // true because local connections never timeout
  26. internal override bool IsAlive(float timeout) => true;
  27. // don't ping host client in host mode
  28. protected override void UpdatePing() {}
  29. internal override void Update()
  30. {
  31. base.Update();
  32. // process internal messages so they are applied at the correct time
  33. while (queue.Count > 0)
  34. {
  35. // call receive on queued writer's content, return to pool
  36. NetworkWriterPooled writer = queue.Dequeue();
  37. ArraySegment<byte> message = writer.ToArraySegment();
  38. // OnTransportData assumes a proper batch with timestamp etc.
  39. // let's make a proper batch and pass it to OnTransportData.
  40. Batcher batcher = GetBatchForChannelId(Channels.Reliable);
  41. batcher.AddMessage(message, NetworkTime.localTime);
  42. using (NetworkWriterPooled batchWriter = NetworkWriterPool.Get())
  43. {
  44. // make a batch with our local time (double precision)
  45. if (batcher.GetBatch(batchWriter))
  46. {
  47. NetworkServer.OnTransportData(connectionId, batchWriter.ToArraySegment(), Channels.Reliable);
  48. }
  49. }
  50. NetworkWriterPool.Return(writer);
  51. }
  52. }
  53. internal void DisconnectInternal()
  54. {
  55. // set not ready and handle clientscene disconnect in any case
  56. // (might be client or host mode here)
  57. isReady = false;
  58. RemoveFromObservingsObservers();
  59. }
  60. /// <summary>Disconnects this connection.</summary>
  61. public override void Disconnect()
  62. {
  63. DisconnectInternal();
  64. connectionToServer.DisconnectInternal();
  65. }
  66. }
  67. }