ConnectionEvents.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. using System;
  2. using System.Collections.Concurrent;
  3. using Best.HTTP.HostSetting;
  4. using Best.HTTP.Shared;
  5. using Best.HTTP.Shared.Extensions;
  6. using Best.HTTP.Shared.Logger;
  7. namespace Best.HTTP.Hosts.Connections
  8. {
  9. public enum ConnectionEvents
  10. {
  11. StateChange,
  12. ProtocolSupport
  13. }
  14. public readonly struct ConnectionEventInfo
  15. {
  16. public readonly ConnectionBase Source;
  17. public readonly ConnectionEvents Event;
  18. public readonly HTTPConnectionStates State;
  19. public readonly HostProtocolSupport ProtocolSupport;
  20. public readonly HTTPRequest Request;
  21. public readonly HTTPRequestStates RequestState;
  22. public ConnectionEventInfo(ConnectionBase sourceConn, ConnectionEvents @event)
  23. {
  24. this.Source = sourceConn;
  25. this.Event = @event;
  26. this.State = HTTPConnectionStates.Initial;
  27. this.ProtocolSupport = HostProtocolSupport.Unknown;
  28. this.Request = null;
  29. this.RequestState = HTTPRequestStates.Initial;
  30. }
  31. public ConnectionEventInfo(ConnectionBase sourceConn, HTTPConnectionStates newState)
  32. {
  33. this.Source = sourceConn;
  34. this.Event = ConnectionEvents.StateChange;
  35. this.State = newState;
  36. this.ProtocolSupport = HostProtocolSupport.Unknown;
  37. this.Request = null;
  38. this.RequestState = HTTPRequestStates.Initial;
  39. }
  40. public ConnectionEventInfo(ConnectionBase sourceConn, HostProtocolSupport protocolSupport)
  41. {
  42. this.Source = sourceConn;
  43. this.Event = ConnectionEvents.ProtocolSupport;
  44. this.State = HTTPConnectionStates.Initial;
  45. this.ProtocolSupport = protocolSupport;
  46. this.Request = null;
  47. this.RequestState = HTTPRequestStates.Initial;
  48. }
  49. public ConnectionEventInfo(ConnectionBase sourceConn, HTTPRequest request)
  50. {
  51. this.Source = sourceConn;
  52. this.Event = ConnectionEvents.StateChange;
  53. this.State = HTTPConnectionStates.ClosedResendRequest;
  54. this.ProtocolSupport = HostProtocolSupport.Unknown;
  55. this.Request = request;
  56. this.RequestState = HTTPRequestStates.Initial;
  57. }
  58. public override string ToString()
  59. {
  60. switch(this.Event)
  61. {
  62. case ConnectionEvents.StateChange: return $"[ConnectionEventInfo Source: {this.Source.ToString()} To State: {this.State}]";
  63. case ConnectionEvents.ProtocolSupport: return $"[ConnectionEventInfo Source: {this.Source.ToString()} ProtocolSupport: {this.ProtocolSupport}]";
  64. default: return string.Format("[ConnectionEventInfo SourceConnection: {0}, Event: {1}, State: {2}, ProtocolSupport: {3}]", this.Source.ToString(), this.Event, this.State, this.ProtocolSupport);
  65. }
  66. }
  67. }
  68. public static class ConnectionEventHelper
  69. {
  70. private static ConcurrentQueue<ConnectionEventInfo> connectionEventQueue = new ConcurrentQueue<ConnectionEventInfo>();
  71. #pragma warning disable 0649
  72. public static Action<ConnectionEventInfo> OnEvent;
  73. #pragma warning restore
  74. public static void EnqueueConnectionEvent(ConnectionEventInfo @event)
  75. {
  76. if (HTTPManager.Logger.Level == Loglevels.All)
  77. HTTPManager.Logger.Information("ConnectionEventHelper", "Enqueue " + @event.ToString(), @event.Source.Context);
  78. connectionEventQueue.Enqueue(@event);
  79. }
  80. internal static void Clear()
  81. {
  82. connectionEventQueue.Clear();
  83. }
  84. internal static void ProcessQueue()
  85. {
  86. ConnectionEventInfo connectionEvent;
  87. while (connectionEventQueue.TryDequeue(out connectionEvent))
  88. {
  89. //if (HTTPManager.Logger.Level == Loglevels.All)
  90. // HTTPManager.Logger.Information("ConnectionEventHelper", "Processing connection event: " + connectionEvent.ToString(), connectionEvent.Source.Context);
  91. if (OnEvent != null)
  92. {
  93. try
  94. {
  95. OnEvent(connectionEvent);
  96. }
  97. catch (Exception ex)
  98. {
  99. HTTPManager.Logger.Exception("ConnectionEventHelper", "ProcessQueue", ex, connectionEvent.Source.Context);
  100. }
  101. }
  102. if (connectionEvent.Source.LastProcessedUri == null)
  103. {
  104. HTTPManager.Logger.Information("ConnectionEventHelper", String.Format("Ignoring ConnectionEventInfo({0}) because its LastProcessedUri is null!", connectionEvent.ToString()), connectionEvent.Source.Context);
  105. return;
  106. }
  107. switch (connectionEvent.Event)
  108. {
  109. case ConnectionEvents.StateChange:
  110. HandleConnectionStateChange(connectionEvent);
  111. break;
  112. case ConnectionEvents.ProtocolSupport:
  113. HostManager.GetHostVariant(connectionEvent.Source)
  114. .AddProtocol(connectionEvent.ProtocolSupport);
  115. break;
  116. }
  117. }
  118. }
  119. private static void HandleConnectionStateChange(ConnectionEventInfo @event)
  120. {
  121. try
  122. {
  123. var connection = @event.Source;
  124. switch (@event.State)
  125. {
  126. case HTTPConnectionStates.Recycle:
  127. HostManager.GetHostVariant(connection)
  128. .RecycleConnection(connection)
  129. .TryToSendQueuedRequests();
  130. break;
  131. case HTTPConnectionStates.WaitForProtocolShutdown:
  132. HostManager.GetHostVariant(connection)
  133. .RemoveConnection(connection, @event.State);
  134. break;
  135. case HTTPConnectionStates.Closed:
  136. case HTTPConnectionStates.ClosedResendRequest:
  137. // in case of ClosedResendRequest
  138. if (@event.Request != null)
  139. RequestEventHelper.EnqueueRequestEvent(new RequestEventInfo(@event.Request, RequestEvents.Resend));
  140. if (connection.LastProcessedUri == null)
  141. UnityEngine.Debug.LogError($"{connection} - LastProcessedUri is null!");
  142. HostManager.GetHostVariant(connection)
  143. .RemoveConnection(connection, @event.State)
  144. .TryToSendQueuedRequests();
  145. break;
  146. }
  147. }
  148. catch (Exception ex)
  149. {
  150. HTTPManager.Logger.Exception("ConnectionEvents", $"HandleConnectionStateChange ({@event.State})", ex, @event.Source.Context);
  151. }
  152. }
  153. }
  154. }