private static void SendRequestImpl(HTTPRequest request) { HTTPConnection conn = FindOrCreateFreeConnection(request); if (conn != null) { // found a free connection: put it in the ActiveConnection list(they will be checked periodically in the OnUpdate call) if (ActiveConnections.Find((c) => c == conn) == null) { ActiveConnections.Add(conn); } FreeConnections.Remove(conn); request.State = HTTPRequestStates.Processing; request.Prepare(); // then start process the request conn.Process(request); } else { // If no free connection found and creation prohibited, we will put back to the queue request.State = HTTPRequestStates.Queued; RequestQueue.Add(request); } }
private static HTTPConnection FindOrCreateFreeConnection(Uri uri) { HTTPConnection hTTPConnection = null; string text = new UriBuilder(uri.Scheme, uri.Host, uri.Port).Uri.ToString(); if (Connections.TryGetValue(text, out List <HTTPConnection> value)) { for (int i = 0; i < value.Count; i++) { if (hTTPConnection != null) { break; } if (value[i] != null && value[i].IsFree) { hTTPConnection = value[i]; } } } else { Connections.Add(text, value = new List <HTTPConnection>(MaxConnectionPerServer)); } if (hTTPConnection == null) { if (value.Count == MaxConnectionPerServer) { return(null); } value.Add(hTTPConnection = new HTTPConnection(text)); } return(hTTPConnection); }
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); } } }
private static HTTPConnection FindOrCreateFreeConnection(HTTPRequest request) { HTTPConnection conn = null; List <HTTPConnection> connections; string serverUrl = GetKeyForRequest(request); if (Connections.TryGetValue(serverUrl, out connections)) { // count active connections int activeConnections = 0; for (int i = 0; i < connections.Count; ++i) { if (connections [i].State < HTTPConnectionStates.Free) { activeConnections++; } } if (activeConnections <= MaxConnectionPerServer) { // search for a Free connection for (int i = 0; i < connections.Count && conn == null; ++i) { var tmpConn = connections [i]; if (tmpConn != null && tmpConn.IsFree && (!tmpConn.HasProxy || tmpConn.LastProcessedUri == null || tmpConn.LastProcessedUri.Host.Equals(request.CurrentUri.Host, StringComparison.OrdinalIgnoreCase))) { conn = tmpConn; } } } } else { Connections.Add(serverUrl, connections = new List <HTTPConnection> (MaxConnectionPerServer)); } // No free connection found? if (conn == null) { // Max connection reached? if (connections.Count >= MaxConnectionPerServer) { return(null); } // if no, create a new one connections.Add(conn = new HTTPConnection(serverUrl)); } return(conn); }
public bool MoveNext() { lock (HTTPManager.Locker) { HTTPConnection connection = HTTPManager.GetConnectionWith(this); return(connection != null && connection.State <= HTTPConnectionStates.WaitForRecycle); } }
private static HTTPConnection FindOrCreateFreeConnection(Uri uri) { HTTPConnection conn = null; // HTTP and HTTPS needs different connections. string serverUrl = new UriBuilder(uri.Scheme, uri.Host, uri.Port).Uri.ToString(); conn = new HTTPConnection(serverUrl); return(conn); }
public bool MoveNext() { object locker = HTTPManager.Locker; bool result; lock (locker) { HTTPConnection connectionWith = HTTPManager.GetConnectionWith(this); result = (connectionWith != null && connectionWith.State <= HTTPConnectionStates.WaitForRecycle); } return(result); }
private static void SendRequestImpl(HTTPRequest request) { HTTPConnection conn = FindOrCreateFreeConnection(request.CurrentUri); if (conn != null) { if (ActiveConnections.Find((HTTPConnection c) => c == conn) == null) { ActiveConnections.Add(conn); } conn.Process(request); } else { RequestQueue.Add(request); } }
private static HTTPConnection FindOrCreateFreeConnection(HTTPRequest request) { HTTPConnection hTTPConnection = null; string keyForRequest = HTTPManager.GetKeyForRequest(request); List <HTTPConnection> list; if (HTTPManager.Connections.TryGetValue(keyForRequest, out list)) { int num = 0; for (int i = 0; i < list.Count; i++) { if (list[i].State < HTTPConnectionStates.Free) { num++; } } if (num <= (int)HTTPManager.MaxConnectionPerServer) { int num2 = 0; while (num2 < list.Count && hTTPConnection == null) { HTTPConnection hTTPConnection2 = list[num2]; if (hTTPConnection2 != null && hTTPConnection2.IsFree && (!hTTPConnection2.HasProxy || hTTPConnection2.LastProcessedUri == null || hTTPConnection2.LastProcessedUri.Host.Equals(request.CurrentUri.Host, StringComparison.OrdinalIgnoreCase))) { hTTPConnection = hTTPConnection2; } num2++; } } } else { HTTPManager.Connections.Add(keyForRequest, list = new List <HTTPConnection>((int)HTTPManager.MaxConnectionPerServer)); } if (hTTPConnection == null) { if (list.Count >= (int)HTTPManager.MaxConnectionPerServer) { return(null); } list.Add(hTTPConnection = new HTTPConnection(keyForRequest)); } return(hTTPConnection); }
internal static HTTPConnection GetConnectionWith(HTTPRequest request) { object locker = HTTPManager.Locker; HTTPConnection result; lock (locker) { for (int i = 0; i < HTTPManager.ActiveConnections.Count; i++) { HTTPConnection hTTPConnection = HTTPManager.ActiveConnections[i]; if (hTTPConnection.CurrentRequest == request) { result = hTTPConnection; return(result); } } result = null; } return(result); }
private static void SendRequestImpl(HTTPRequest request) { HTTPConnection conn = HTTPManager.FindOrCreateFreeConnection(request); if (conn != null) { if (HTTPManager.ActiveConnections.Find((HTTPConnection c) => c == conn) == null) { HTTPManager.ActiveConnections.Add(conn); } HTTPManager.FreeConnections.Remove(conn); request.State = HTTPRequestStates.Processing; request.Prepare(); conn.Process(request); } else { request.State = HTTPRequestStates.Queued; HTTPManager.RequestQueue.Add(request); } }
private static HTTPConnection FindOrCreateFreeConnection(Uri uri) { HTTPConnection conn = null; List <HTTPConnection> connections; // HTTP and HTTPS needs different connections. string serverUrl = new UriBuilder(uri.Scheme, uri.Host, uri.Port).Uri.ToString(); if (Connections.TryGetValue(serverUrl, out connections)) { // search for a Free connection for (int i = 0; i < connections.Count && conn == null; ++i) { if (connections[i] != null && connections[i].IsFree) { conn = connections[i]; } } } else { Connections.Add(serverUrl, connections = new List <HTTPConnection>(MaxConnectionPerServer)); } // No free connection found? if (conn == null) { // Max connection reached? if (connections.Count == MaxConnectionPerServer) { return(null); } // if no, create a new one connections.Add(conn = new HTTPConnection(serverUrl)); } return(conn); }
private static void RecycleConnection(HTTPConnection conn) { conn.Recycle(); RecycledConnections.Add(conn); }
private static HTTPConnection FindOrCreateFreeConnection(HTTPRequest request) { HTTPConnection conn = null; List<HTTPConnection> connections; string serverUrl = GetKeyForRequest(request); if (Connections.TryGetValue(serverUrl, out connections)) { // count active connections int activeConnections = 0; for (int i = 0; i < connections.Count; ++i) if (connections[i].IsActive) activeConnections++; if (activeConnections <= MaxConnectionPerServer) // search for a Free connection for (int i = 0; i < connections.Count && conn == null; ++i) { var tmpConn = connections[i]; if (tmpConn != null && tmpConn.IsFree && (!tmpConn.HasProxy || tmpConn.LastProcessedUri == null || tmpConn.LastProcessedUri.Host.Equals(request.CurrentUri.Host, StringComparison.OrdinalIgnoreCase))) conn = tmpConn; } } else Connections.Add(serverUrl, connections = new List<HTTPConnection>(MaxConnectionPerServer)); // No free connection found? if (conn == null) { // Max connection reached? if (connections.Count >= MaxConnectionPerServer) return null; // if no, create a new one connections.Add(conn = new HTTPConnection(serverUrl)); } return conn; }
/// <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(); } }
/// <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]); } } } }
internal static void OnUpdate() { IsCallingCallbacks = true; try { for (int i = 0; i < ActiveConnections.Count; i++) { HTTPConnection hTTPConnection = ActiveConnections[i]; switch (hTTPConnection.State) { case HTTPConnectionStates.Processing: if (hTTPConnection.CurrentRequest.UseStreaming && hTTPConnection.CurrentRequest.Response != null && hTTPConnection.CurrentRequest.Response.HasStreamedFragments()) { hTTPConnection.HandleCallback(); } break; case HTTPConnectionStates.Redirected: SendRequest(hTTPConnection.CurrentRequest); RecycleConnection(hTTPConnection); break; case HTTPConnectionStates.WaitForRecycle: hTTPConnection.CurrentRequest.FinishStreaming(); hTTPConnection.HandleCallback(); RecycleConnection(hTTPConnection); break; case HTTPConnectionStates.Upgraded: hTTPConnection.HandleCallback(); break; case HTTPConnectionStates.WaitForProtocolShutdown: { WebSocketResponse webSocketResponse = hTTPConnection.CurrentRequest.Response as WebSocketResponse; webSocketResponse.HandleEvents(); if (webSocketResponse.IsClosed) { hTTPConnection.HandleCallback(); hTTPConnection.Dispose(); RecycleConnection(hTTPConnection); } break; } case HTTPConnectionStates.Closed: hTTPConnection.CurrentRequest.FinishStreaming(); hTTPConnection.HandleCallback(); RecycleConnection(hTTPConnection); Connections[hTTPConnection.ServerAddress].Remove(hTTPConnection); break; case HTTPConnectionStates.Free: if (hTTPConnection.IsRemovable) { hTTPConnection.Dispose(); Connections[hTTPConnection.ServerAddress].Remove(hTTPConnection); } break; } } } finally { IsCallingCallbacks = false; } if (RecycledConnections.Count > 0) { for (int j = 0; j < RecycledConnections.Count; j++) { if (RecycledConnections[j].IsFree) { ActiveConnections.Remove(RecycledConnections[j]); } } RecycledConnections.Clear(); } if (RequestQueue.Count > 0) { HTTPRequest[] array = RequestQueue.ToArray(); RequestQueue.Clear(); for (int k = 0; k < array.Length; k++) { SendRequest(array[k]); } } }
private static HTTPConnection FindOrCreateFreeConnection(Uri uri) { HTTPConnection conn = null; // HTTP and HTTPS needs different connections. string serverUrl = new UriBuilder(uri.Scheme, uri.Host, uri.Port).Uri.ToString(); conn = new HTTPConnection(serverUrl); return conn; }
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(); } }