public void Abort() { object locker = HTTPManager.Locker; lock (locker) { HTTPConnection connectionWith = HTTPManager.GetConnectionWith(this); if (connectionWith == null) { if (!HTTPManager.RemoveFromQueue(this)) { HTTPManager.Logger.Warning("HTTPRequest", "Abort - No active connection found with this request! (The request may already finished?)"); } this.State = HTTPRequestStates.Aborted; } else { if (this.Response != null && this.Response.IsStreamed) { this.Response.Dispose(); } connectionWith.Abort(HTTPConnectionStates.AbortRequested); } } }
/// <summary> /// Update function that should be called regularly from a Unity event(Update, LateUpdate). Callbacks are dispatched from this function. /// </summary> public static void OnUpdate() { lock (Locker) { IsCallingCallbacks = true; try { for (int i = 0; i < ActiveConnections.Count; ++i) { HTTPConnection conn = ActiveConnections [i]; switch (conn.State) { case HTTPConnectionStates.Processing: conn.HandleProgressCallback(); if (conn.CurrentRequest.UseStreaming && conn.CurrentRequest.Response != null && conn.CurrentRequest.Response.HasStreamedFragments()) { conn.HandleCallback(); } if (((!conn.CurrentRequest.UseStreaming && conn.CurrentRequest.UploadStream == null) || conn.CurrentRequest.EnableTimoutForStreaming) && DateTime.UtcNow - conn.StartTime > conn.CurrentRequest.Timeout) { conn.Abort(HTTPConnectionStates.TimedOut); } break; case HTTPConnectionStates.TimedOut: if (DateTime.UtcNow - conn.TimedOutStart > TimeSpan.FromMilliseconds(500)) { HTTPManager.Logger.Information("HTTPManager", "Hard aborting connection becouse of a long waiting TimedOut state"); conn.CurrentRequest.Response = null; conn.CurrentRequest.State = HTTPRequestStates.TimedOut; conn.HandleCallback(); RecycleConnection(conn); } break; case HTTPConnectionStates.Redirected: // If the server redirected us, we need to find or create a connection to the new server and send out the request again. SendRequest(conn.CurrentRequest); RecycleConnection(conn); break; case HTTPConnectionStates.WaitForRecycle: // If it's a streamed request, it's finished now conn.CurrentRequest.FinishStreaming(); // Call the callback conn.HandleCallback(); // Then recycle the connection RecycleConnection(conn); break; case HTTPConnectionStates.Upgraded: // The connection upgraded to an other protocol conn.HandleCallback(); break; case HTTPConnectionStates.WaitForProtocolShutdown: var ws = conn.CurrentRequest.Response as WebSocket.WebSocketResponse; if (ws != null) { ws.HandleEvents(); } if (ws == null || ws.IsClosed) { conn.HandleCallback(); // After both sending and receiving a Close message, an endpoint considers the WebSocket connection closed and MUST close the underlying TCP connection. conn.Dispose(); RecycleConnection(conn); } break; case HTTPConnectionStates.AbortRequested: // Corner case: we aborted a WebSocket connection { ws = conn.CurrentRequest.Response as WebSocket.WebSocketResponse; if (ws != null) { ws.HandleEvents(); if (ws.IsClosed) { conn.HandleCallback(); conn.Dispose(); RecycleConnection(conn); } } } break; case HTTPConnectionStates.Closed: // If it's a streamed request, it's finished now conn.CurrentRequest.FinishStreaming(); // Call the callback conn.HandleCallback(); // It will remove from the ActiveConnections RecycleConnection(conn); break; } } } finally { IsCallingCallbacks = false; } if (RecycledConnections.Count > 0) { for (int i = 0; i < RecycledConnections.Count; ++i) { var connection = RecycledConnections [i]; // If in a callback made a request that aquired this connection, then we will not remove it from the // active connections. if (connection.IsFree) { ActiveConnections.Remove(connection); FreeConnections.Add(connection); } } RecycledConnections.Clear(); } if (FreeConnections.Count > 0) { for (int i = 0; i < FreeConnections.Count; i++) { var connection = FreeConnections [i]; if (connection.IsRemovable) { // Remove the connection from the connection reference table List <HTTPConnection> connections = null; if (Connections.TryGetValue(connection.ServerAddress, out connections)) { connections.Remove(connection); } // Dispose the connection connection.Dispose(); FreeConnections.RemoveAt(i); i--; } } } if (CanProcessFromQueue()) { // Sort the queue by priority, only if we have to if (RequestQueue.Find((req) => req.Priority != 0) != null) { RequestQueue.Sort((req1, req2) => req1.Priority - req2.Priority); } // Create an array from the queue and clear it. When we call the SendRequest while still no room for new connections, the same queue will be rebuilt. var queue = RequestQueue.ToArray(); RequestQueue.Clear(); for (int i = 0; i < queue.Length; ++i) { SendRequest(queue [i]); } } } // lock(Locker) if (heartbeats != null) { heartbeats.Update(); } }
public static void OnUpdate() { object locker = HTTPManager.Locker; lock (locker) { HTTPManager.IsCallingCallbacks = true; try { for (int i = 0; i < HTTPManager.ActiveConnections.Count; i++) { HTTPConnection hTTPConnection = HTTPManager.ActiveConnections[i]; switch (hTTPConnection.State) { case HTTPConnectionStates.Processing: hTTPConnection.HandleProgressCallback(); if (hTTPConnection.CurrentRequest.UseStreaming && hTTPConnection.CurrentRequest.Response != null && hTTPConnection.CurrentRequest.Response.HasStreamedFragments()) { hTTPConnection.HandleCallback(); } if (((!hTTPConnection.CurrentRequest.UseStreaming && hTTPConnection.CurrentRequest.UploadStream == null) || hTTPConnection.CurrentRequest.EnableTimoutForStreaming) && DateTime.UtcNow - hTTPConnection.StartTime > hTTPConnection.CurrentRequest.Timeout) { hTTPConnection.Abort(HTTPConnectionStates.TimedOut); } break; case HTTPConnectionStates.Redirected: HTTPManager.SendRequest(hTTPConnection.CurrentRequest); HTTPManager.RecycleConnection(hTTPConnection); break; case HTTPConnectionStates.Upgraded: hTTPConnection.HandleCallback(); break; case HTTPConnectionStates.WaitForProtocolShutdown: { WebSocketResponse webSocketResponse = hTTPConnection.CurrentRequest.Response as WebSocketResponse; if (webSocketResponse != null) { webSocketResponse.HandleEvents(); } if (webSocketResponse == null || webSocketResponse.IsClosed) { hTTPConnection.HandleCallback(); hTTPConnection.Dispose(); HTTPManager.RecycleConnection(hTTPConnection); } break; } case HTTPConnectionStates.WaitForRecycle: hTTPConnection.CurrentRequest.FinishStreaming(); hTTPConnection.HandleCallback(); HTTPManager.RecycleConnection(hTTPConnection); break; case HTTPConnectionStates.AbortRequested: { WebSocketResponse webSocketResponse = hTTPConnection.CurrentRequest.Response as WebSocketResponse; if (webSocketResponse != null) { webSocketResponse.HandleEvents(); if (webSocketResponse.IsClosed) { hTTPConnection.HandleCallback(); hTTPConnection.Dispose(); HTTPManager.RecycleConnection(hTTPConnection); } } break; } case HTTPConnectionStates.TimedOut: if (DateTime.UtcNow - hTTPConnection.TimedOutStart > TimeSpan.FromMilliseconds(500.0)) { HTTPManager.Logger.Information("HTTPManager", "Hard aborting connection becouse of a long waiting TimedOut state"); hTTPConnection.CurrentRequest.Response = null; hTTPConnection.CurrentRequest.State = HTTPRequestStates.TimedOut; hTTPConnection.HandleCallback(); HTTPManager.RecycleConnection(hTTPConnection); } break; case HTTPConnectionStates.Closed: hTTPConnection.CurrentRequest.FinishStreaming(); hTTPConnection.HandleCallback(); HTTPManager.RecycleConnection(hTTPConnection); break; } } } finally { HTTPManager.IsCallingCallbacks = false; } if (HTTPManager.RecycledConnections.Count > 0) { for (int j = 0; j < HTTPManager.RecycledConnections.Count; j++) { HTTPConnection hTTPConnection2 = HTTPManager.RecycledConnections[j]; if (hTTPConnection2.IsFree) { HTTPManager.ActiveConnections.Remove(hTTPConnection2); HTTPManager.FreeConnections.Add(hTTPConnection2); } } HTTPManager.RecycledConnections.Clear(); } if (HTTPManager.FreeConnections.Count > 0) { for (int k = 0; k < HTTPManager.FreeConnections.Count; k++) { HTTPConnection hTTPConnection3 = HTTPManager.FreeConnections[k]; if (hTTPConnection3.IsRemovable) { List <HTTPConnection> list = null; if (HTTPManager.Connections.TryGetValue(hTTPConnection3.ServerAddress, out list)) { list.Remove(hTTPConnection3); } hTTPConnection3.Dispose(); HTTPManager.FreeConnections.RemoveAt(k); k--; } } } if (HTTPManager.CanProcessFromQueue()) { if (HTTPManager.RequestQueue.Find((HTTPRequest req) => req.Priority != 0) != null) { HTTPManager.RequestQueue.Sort((HTTPRequest req1, HTTPRequest req2) => req1.Priority - req2.Priority); } HTTPRequest[] array = HTTPManager.RequestQueue.ToArray(); HTTPManager.RequestQueue.Clear(); for (int l = 0; l < array.Length; l++) { HTTPManager.SendRequest(array[l]); } } } if (HTTPManager.heartbeats != null) { HTTPManager.heartbeats.Update(); } }
/// <summary> /// Update function that should be called regularly from a Unity event(Update, LateUpdate). Callbacks are dispatched from this function. /// </summary> public static void OnUpdate() { lock (Locker) { IsCallingCallbacks = true; try { for (int i = 0; i < ActiveConnections.Count; ++i) { HTTPConnection conn = ActiveConnections[i]; switch (conn.State) { case HTTPConnectionStates.Processing: conn.HandleProgressCallback(); if (conn.CurrentRequest.UseStreaming && conn.CurrentRequest.Response != null && conn.CurrentRequest.Response.HasStreamedFragments()) { conn.HandleCallback(); } if ( /*(!conn.CurrentRequest.UseStreaming || conn.CurrentRequest.EnableTimoutForStreaming) &&*/ DateTime.UtcNow - conn.StartTime > conn.CurrentRequest.Timeout) { conn.Abort(HTTPConnectionStates.TimedOut); } break; case HTTPConnectionStates.Redirected: // If the server redirected us, we need to find or create a connection to the new server and send out the request again. SendRequest(conn.CurrentRequest); RecycleConnection(conn); break; case HTTPConnectionStates.WaitForRecycle: // If it's a streamed request, it's finished now conn.CurrentRequest.FinishStreaming(); // Call the callback conn.HandleCallback(); // Then recycle the connection RecycleConnection(conn); break; case HTTPConnectionStates.Upgraded: // The connection upgraded to an other protocol conn.HandleCallback(); break; case HTTPConnectionStates.WaitForProtocolShutdown: var ws = conn.CurrentRequest.Response as WebSocket.WebSocketResponse; ws.HandleEvents(); if (ws.IsClosed) { conn.HandleCallback(); // After both sending and receiving a Close message, an endpoint considers the WebSocket connection closed and MUST close the underlying TCP connection. conn.Dispose(); RecycleConnection(conn); } break; case HTTPConnectionStates.Closed: // If it's a streamed request, it's finished now conn.CurrentRequest.FinishStreaming(); // Call the callback conn.HandleCallback(); // It will remove from the ActiveConnections RecycleConnection(conn); // Remove from the useable connections Connections[conn.ServerAddress].Remove(conn); break; case HTTPConnectionStates.Free: if (conn.IsRemovable) { conn.Dispose(); // Remove from the useable connections Connections[conn.ServerAddress].Remove(conn); } break; } } } finally { IsCallingCallbacks = false; } if (RecycledConnections.Count > 0) { for (int i = 0; i < RecycledConnections.Count; ++i) { // If in a callback made a request that aquired this connection, then we will not remove it from the // active connections. if (RecycledConnections[i].IsFree) { ActiveConnections.Remove(RecycledConnections[i]); } } RecycledConnections.Clear(); } if (RequestQueue.Count > 0) { var queue = RequestQueue.ToArray(); RequestQueue.Clear(); for (int i = 0; i < queue.Length; ++i) { SendRequest(queue[i]); } } } }