private async Task <string> SendAsync(HttpClient client, string data, HttpMethod method, CancellationToken?token = null) { var responseData = string.Empty; var statusCode = HttpStatusCode.OK; var requestData = data; string url; try { url = await BuildUrl(token).ConfigureAwait(false); var message = new HttpRequestMessage(method, url) { Content = new StringContent(requestData) }; CancellationToken invokeToken; if (token == null) { invokeToken = new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token; } else { invokeToken = CancellationTokenSource.CreateLinkedTokenSource(token.Value, new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token).Token; } HttpResponseMessage result = null; result = await client.SendAsync(message, invokeToken).ConfigureAwait(false); statusCode = result.StatusCode; responseData = await result.Content.ReadAsStringAsync().ConfigureAwait(false); result.EnsureSuccessStatusCode(); return(responseData); } catch (OperationCanceledException ex) { throw new FirebaseException(FirebaseExceptionReason.OperationCancelled, ex); } catch (FirebaseException ex) { throw ex; } catch (Exception ex) { throw new FirebaseException(ExceptionHelpers.GetFailureReason(statusCode), ex); } }
private async void ReceiveThread() { while (true) { var url = string.Empty; var line = string.Empty; var statusCode = HttpStatusCode.OK; try { cancel.Token.ThrowIfCancellationRequested(); url = await query.BuildUrl().ConfigureAwait(false); var request = App.Config.HttpStreamFactory.GetStreamHttpRequestMessage(HttpMethod.Get, url); HttpResponseMessage response = null; if (await Task.Run(async delegate { response = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancel.Token).ConfigureAwait(false); return(false); }).WithTimeout(App.Config.DatabaseColdStreamTimeout, true).ConfigureAwait(false)) { continue; } var serverEvent = ServerEventType.KeepAlive; statusCode = response.StatusCode; response.EnsureSuccessStatusCode(); using (var stream = await response.Content.ReadAsStreamAsync()) using (var reader = new NonBlockingStreamReader(stream)) { try { reader.Peek(); // ReadlineAsync bug fix (no idea) } catch { } while (true) { cancel.Token.ThrowIfCancellationRequested(); line = string.Empty; if (await Task.Run(async delegate { line = (await reader.ReadLineAsync().ConfigureAwait(false))?.Trim(); return(false); }).WithTimeout(App.Config.DatabaseColdStreamTimeout, true).ConfigureAwait(false)) { break; } if (string.IsNullOrWhiteSpace(line)) { continue; } var tuple = line.Split(new[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray(); switch (tuple[0].ToLower()) { case "event": serverEvent = ParseServerEvent(serverEvent, tuple[1]); break; case "data": ProcessServerData(url, serverEvent, tuple[1]); break; } if (serverEvent == ServerEventType.AuthRevoked) { // auth token no longer valid, reconnect break; } } } } catch (OperationCanceledException) { break; } catch (Exception ex) { var fireEx = new FirebaseException(ExceptionHelpers.GetFailureReason(statusCode), ex); onError?.Invoke(this, fireEx); } await Task.Delay(App.Config.DatabaseRetryDelay).ConfigureAwait(false); } }
/// <inheritdoc/> public async Task Put(Func <string> jsonData, CancellationToken?token = null, Action <RetryExceptionEventArgs> onException = null) { async Task invoke(Func <string> invokeJsonData) { string url; var responseData = string.Empty; var statusCode = HttpStatusCode.OK; if (App.Config.OfflineMode) { throw new FirebaseException(FirebaseExceptionReason.OfflineMode, new Exception("Offline mode")); } var c = GetClient(); var currentJsonToInvoke = invokeJsonData(); if (currentJsonToInvoke == null) { try { url = await BuildUrl(token).ConfigureAwait(false); CancellationToken invokeToken; if (token == null) { invokeToken = new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token; } else { invokeToken = CancellationTokenSource.CreateLinkedTokenSource(token.Value, new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token).Token; } var result = await c.DeleteAsync(url, invokeToken).ConfigureAwait(false); statusCode = result.StatusCode; responseData = await result.Content.ReadAsStringAsync().ConfigureAwait(false); result.EnsureSuccessStatusCode(); } catch (OperationCanceledException ex) { throw new FirebaseException(FirebaseExceptionReason.OperationCancelled, ex); } catch (FirebaseException ex) { throw ex; } catch (Exception ex) { throw new FirebaseException(ExceptionHelpers.GetFailureReason(statusCode), ex); } } else { await Silent().SendAsync(c, currentJsonToInvoke, HttpMethod.Put, token).ConfigureAwait(false); } }; async Task recursive() { try { await invoke(jsonData).ConfigureAwait(false); } catch (Exception ex) { var retryEx = new RetryExceptionEventArgs(ex, Task.Run(async delegate { await Task.Delay(App.Config.DatabaseRetryDelay).ConfigureAwait(false); return(false); })); onException?.Invoke(retryEx); if (retryEx.Retry != null) { if (await retryEx.Retry) { await recursive().ConfigureAwait(false); } } } } await recursive().ConfigureAwait(false); }
/// <inheritdoc/> public async Task <string> Get(CancellationToken?token = null, Action <RetryExceptionEventArgs> onException = null) { async Task <string> invoke() { var url = string.Empty; var responseData = string.Empty; var statusCode = HttpStatusCode.OK; if (App.Config.OfflineMode) { throw new FirebaseException(FirebaseExceptionReason.OfflineMode, new Exception("Offline mode")); } try { url = await BuildUrl(token).ConfigureAwait(false); CancellationToken invokeToken; if (token == null) { invokeToken = new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token; } else { invokeToken = CancellationTokenSource.CreateLinkedTokenSource(token.Value, new CancellationTokenSource(App.Config.DatabaseRequestTimeout).Token).Token; } var response = await GetClient().GetAsync(url, invokeToken).ConfigureAwait(false); statusCode = response.StatusCode; responseData = await response.Content.ReadAsStringAsync().ConfigureAwait(false); response.EnsureSuccessStatusCode(); response.Dispose(); return(responseData); } catch (OperationCanceledException ex) { throw new FirebaseException(FirebaseExceptionReason.OperationCancelled, ex); } catch (FirebaseException ex) { throw ex; } catch (Exception ex) { throw new FirebaseException(ExceptionHelpers.GetFailureReason(statusCode), ex); } } async Task <string> recursive() { try { return(await invoke().ConfigureAwait(false)); } catch (Exception ex) { var retryEx = new RetryExceptionEventArgs(ex, Task.Run(async delegate { await Task.Delay(App.Config.DatabaseRetryDelay).ConfigureAwait(false); return(false); })); onException?.Invoke(retryEx); if (retryEx.Retry != null) { if (await retryEx.Retry) { await recursive().ConfigureAwait(false); } } return(null); } } return(await recursive().ConfigureAwait(false)); }