protected override async Task <T> InvokeExportAsync <T>( NodeInvocationInfo invocationInfo, CancellationToken cancellationToken) { var payloadJson = JsonConvert.SerializeObject(invocationInfo, jsonSerializerSettings); var payload = new StringContent(payloadJson, Encoding.UTF8, "application/json"); var response = await _client.PostAsync(_endpoint, payload, cancellationToken); if (!response.IsSuccessStatusCode) { // Unfortunately there's no true way to cancel ReadAsStringAsync calls, hence AbandonIfCancelled var responseJson = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); var responseError = JsonConvert.DeserializeObject <RpcJsonResponse>(responseJson, jsonSerializerSettings); throw new NodeInvocationException(responseError.ErrorMessage, responseError.ErrorDetails); } var responseContentType = response.Content.Headers.ContentType; switch (responseContentType.MediaType) { case "text/plain": // String responses can skip JSON encoding/decoding if (typeof(T) != typeof(string)) { throw new ArgumentException( "Node module responded with non-JSON string. This cannot be converted to the requested generic type: " + typeof(T).FullName); } var responseString = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); return((T)(object)responseString); case "application/json": var responseJson = await response.Content.ReadAsStringAsync().OrThrowOnCancellation(cancellationToken); return(JsonConvert.DeserializeObject <T>(responseJson, jsonSerializerSettings)); case "application/octet-stream": // Streamed responses have to be received as System.IO.Stream instances if (typeof(T) != typeof(Stream) && typeof(T) != typeof(object)) { throw new ArgumentException( "Node module responded with binary stream. This cannot be converted to the requested generic type: " + typeof(T).FullName + ". Instead you must use the generic type System.IO.Stream."); } return((T)(object)(await response.Content.ReadAsStreamAsync().OrThrowOnCancellation(cancellationToken))); default: throw new InvalidOperationException("Unexpected response content type: " + responseContentType.MediaType); } }
/// <summary> /// Asynchronously invokes code in the Node.js instance. /// </summary> /// <typeparam name="T">The JSON-serializable data type that the Node.js code will asynchronously return.</typeparam> /// <param name="invocationInfo">Specifies the Node.js function to be invoked and arguments to be passed to it.</param> /// <param name="cancellationToken">A <see cref="CancellationToken"/> that can be used to cancel the invocation.</param> /// <returns>A <see cref="Task{TResult}"/> representing the completion of the RPC call.</returns> protected abstract Task <T> InvokeExportAsync <T>( NodeInvocationInfo invocationInfo, CancellationToken cancellationToken);