/// <summary> /// /// </summary> /// <param name="method"></param> /// <param name="obj"></param> /// <returns></returns> private string SerializeToJson(GrpcServiceMethod method, object obj) { if (method.JsonSerializer != null) { return(method.JsonSerializer.Serialize(obj)); } if (m_Settings.JsonSerializer != null) { return(m_Settings.JsonSerializer.Serialize(obj)); } return(GrpcGatewaySettings.DefaultJsonSerializer.Serialize(obj)); }
/// <summary> /// /// </summary> /// <param name="method"></param> /// <param name="json"></param> /// <param name="objectType"></param> /// <returns></returns> private object DeselializeFromJson(GrpcServiceMethod method, string json, Type objectType) { if (method.JsonSerializer != null) { return(method.JsonSerializer.Deserialize(json, objectType)); } if (m_Settings.JsonSerializer != null) { return(m_Settings.JsonSerializer.Deserialize(json, objectType)); } return(GrpcGatewaySettings.DefaultJsonSerializer.Deserialize(json, objectType)); }
/// <summary> /// /// </summary> /// <param name="method"></param> /// <param name="ex"></param> /// <param name="responseStatus"></param> /// <param name="responseObject"></param> /// <returns></returns> private bool HandleException(GrpcServiceMethod method, Exception ex, out System.Net.HttpStatusCode?responseStatus, out object responseObject) { if (method.ExceptionHandler != null) { if (method.ExceptionHandler(ex, out responseStatus, out responseObject)) { return(true); } } if (m_Settings.ExceptionHandler != null) { if (m_Settings.ExceptionHandler(ex, out responseStatus, out responseObject)) { return(true); } } return(ExceptionHandlers.NotHandle(ex, out responseStatus, out responseObject)); }
/// <summary> /// /// </summary> /// <param name="method"></param> /// <param name="headers"></param> /// <param name="requestObject"></param> /// <returns></returns> private Task <object> CallGrpcAsync(GrpcServiceMethod method, IDictionary <string, string> headers, object requestObject) { object requests; if (requestObject != null && typeof(IEnumerable <>).MakeGenericType(method.RequestType).IsAssignableFrom(requestObject.GetType())) { requests = requestObject; } else { Array ary = Array.CreateInstance(method.RequestType, 1); ary.SetValue(requestObject, 0); requests = ary; } System.Reflection.MethodInfo m = typeof(GrpcGatewayMiddleware).GetMethod("CallGrpcAsyncCore", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); Task <object> task = (Task <object>)m.MakeGenericMethod(new Type[] { method.RequestType, method.ResponseType }).Invoke(this, new object[] { method, headers, requests }); return(task); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="method"></param> /// <param name="headers"></param> /// <param name="requests"></param> /// <returns></returns> private Task <object> CallGrpcAsyncCore <TRequest, TResponse>(GrpcServiceMethod method, IDictionary <string, string> headers, IEnumerable <TRequest> requests) where TRequest : class where TResponse : class { CallInvoker invoker = new DefaultCallInvoker(m_Settings.Channel); CallOptions option = CreateCallOptions(headers); Method <TRequest, TResponse> rpc = (Method <TRequest, TResponse>)method.Method; switch (rpc.Type) { case MethodType.Unary: Task <TResponse> taskUnary = AsyncUnaryCall(invoker, rpc, option, requests.FirstOrDefault()); return(Task.FromResult <object>(taskUnary.Result)); case MethodType.ClientStreaming: Task <TResponse> taskClientStreaming = AsyncClientStreamingCall(invoker, rpc, option, requests); return(Task.FromResult <object>(taskClientStreaming.Result)); case MethodType.ServerStreaming: Task <IList <TResponse> > taskServerStreaming = AsyncServerStreamingCall(invoker, rpc, option, requests.FirstOrDefault()); return(Task.FromResult <object>(taskServerStreaming.Result)); case MethodType.DuplexStreaming: Task <IList <TResponse> > taskDuplexStreaming = AsyncDuplexStreamingCall(invoker, rpc, option, requests); return(Task.FromResult <object>(taskDuplexStreaming.Result)); default: throw new NotSupportedException(string.Format("MethodType '{0}' is not supported.", rpc.Type)); } }
/// <summary> /// /// </summary> /// <param name="httpContext"></param> /// <returns></returns> public async Task Invoke(HttpContext httpContext) { GrpcServiceMethod method = null; RpcException rpc; System.Net.HttpStatusCode?errorStatus = null; object errorResponseObject = null; try { string requestPath = httpContext.Request.Path.Value; if (m_ServiceMethods == null || !m_ServiceMethods.TryGetValue(requestPath, out method)) { if (m_Next != null) { await m_Next(httpContext); } return; } IDictionary <string, string> headers = GetRequestHeaders(httpContext, IsGrpcRequestHeader); string requestJson = GetRequestJson(httpContext); object requestObject = DeselializeFromJson(method, requestJson, method.GetJsonRequestType()); object responseObject = await CallGrpcAsync(method, headers, requestObject); string responseJson = SerializeToJson(method, responseObject); httpContext.Response.ContentType = "application/json"; await httpContext.Response.WriteAsync(responseJson); } catch (Exception ex) when(TryGetRpcException(ex, out rpc) && HandleRpcException(method, rpc, out errorStatus, out errorResponseObject)) { if (errorStatus.HasValue) { httpContext.Response.StatusCode = (int)errorStatus; } if (errorResponseObject != null) { await httpContext.Response.WriteAsync(SerializeToJson(method, errorResponseObject)); } } catch (Exception ex) when(HandleException(method, ex, out errorStatus, out errorResponseObject)) { if (errorStatus.HasValue) { httpContext.Response.StatusCode = (int)errorStatus; } if (errorResponseObject != null) { await httpContext.Response.WriteAsync(SerializeToJson(method, errorResponseObject)); } } catch { httpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; } }