private async Task <TResponse> SendAsync <TResponse>(RequestWrapper <TResponse> request, string?route = null) { try { string requestJson = request.Serialize(this.requestSerializer); Uri uri = new Uri(this.BaseUrl, route); List <RpcRequest> requests = request.GetRequests(); var requestContext = new RequestEventContext(route, requests, requestJson); ResponseEventContext?responseContext = null; if (this.Events.OnRequestStartAsync != null) { await this.Events.OnRequestStartAsync(requestContext); } List <RpcResponse>?responses = null; string responseJson; Exception? error = null; responseJson = await this.transportClient.SendRequestAsync(uri, requestJson); try { if (string.IsNullOrWhiteSpace(responseJson)) { throw new RpcClientParseException("Server did not return a rpc response, just an empty body."); } try { TResponse returnValue; (responses, returnValue) = request.Deserialize(responseJson, this.requestSerializer); responseContext = new ResponseEventContext(responseJson, responses); return(returnValue); } catch (Exception ex) { error = ex; throw new RpcClientParseException($"Unable to parse response from server: '{responseJson}'", ex); } } finally { if (this.Events.OnRequestCompleteAsync != null) { if (responseContext == null) { responseContext = new ResponseEventContext(responseJson, responses, error); } await this.Events.OnRequestCompleteAsync(responseContext, requestContext); } } } catch (Exception ex) when(!(ex is RpcClientException) && !(ex is RpcException)) { throw new RpcClientUnknownException("Error occurred when trying to send rpc request(s)", ex); } }
/// <summary> /// Sends the a http request to the server, posting the request in json format /// </summary> /// <param name="request">Request object that will goto the rpc server</param> /// <param name="deserializer">Function to deserialize the json response</param> /// <param name="route">(Optional) Route that will append to the base url if the request method call is not located at the base route</param> /// <param name="resultTypeResolver">(Optional) Function that will determine the deserialization type for the result based on request id. Otherwise the result will be a json string.</param> /// <returns>The response for the sent request</returns> private async Task <List <RpcResponse> > SendAsync(IList <RpcRequest> requests, string route = null, Func <RpcId, Type> resultTypeResolver = null) { if (!requests.Any()) { throw new ArgumentException("There must be at least one rpc request when sending."); } try { string requestJson; if (requests.Count == 1) { requestJson = this.JsonSerializer.Serialize(requests.Single()); } else { requestJson = this.JsonSerializer.SerializeBulk(requests); } Uri uri = new Uri(this.BaseUrl, route); var requestContext = new RequestEventContext(route, requests.ToList(), requestJson); ResponseEventContext responseContext = null; if (this.Events.OnRequestStartAsync != null) { await this.Events.OnRequestStartAsync(requestContext); } Stopwatch stopwatch = Stopwatch.StartNew(); try { string responseJson; try { responseJson = await this.TransportClient.SendRequestAsync(uri, requestJson); } finally { stopwatch.Stop(); } if (string.IsNullOrWhiteSpace(responseJson)) { throw new RpcClientParseException("Server did not return a rpc response, just an empty body."); } List <RpcResponse> responses = null; try { if (requests.Count == 1) { Type resultType = resultTypeResolver?.Invoke(requests.First().Id); RpcResponse response = this.JsonSerializer.Deserialize(responseJson, resultType); responses = new List <RpcResponse> { response }; } else { responses = this.JsonSerializer.DeserializeBulk(responseJson, resultTypeResolver); } responseContext = new ResponseEventContext(stopwatch.Elapsed, responseJson, responses); return(responses); } catch (Exception ex) { responseContext = new ResponseEventContext(stopwatch.Elapsed, responseJson, responses, ex); throw new RpcClientParseException($"Unable to parse response from server: '{responseJson}'", ex); } } finally { if (this.Events.OnRequestCompleteAsync != null) { await this.Events.OnRequestCompleteAsync(responseContext, requestContext); } } } catch (Exception ex) when(!(ex is RpcClientException) && !(ex is RpcException)) { throw new RpcClientUnknownException("Error occurred when trying to send rpc requests(s)", ex); } }