/// <summary> /// 指定された型に対するサービス定義を生成します。 /// </summary> /// <param name="serviceName">サービス名</param> /// <param name="serviceType">サービスの型</param> /// <param name="serviceInstance">サービスインスタンス</param> /// <param name="settings">動作設定</param> /// <returns></returns> public ServerServiceDefinition BuildService(string serviceName, Type serviceType, object serviceInstance, GrpcServiceBuilderSettings settings) { settings = settings ?? new GrpcServiceBuilderSettings(); ServerServiceDefinition.Builder builder = ServerServiceDefinition.CreateBuilder(); Type implType = serviceInstance.GetType(); IList <IGrpcServerMethodInvokingInterceptor> classInvokingInterceptors = GetInvokingInterceptors(implType); IList <IGrpcServerMethodInvokedInterceptor> classInvokedInterceptors = GetInvokedInterceptors(implType); foreach (GrpcMethodHandlerInfo method in GrpcReflection.EnumerateServiceMethods(implType)) { IList <IGrpcServerMethodInvokingInterceptor> methodInvokingInterceptors = GetInvokingInterceptors(method.Handler); IList <IGrpcServerMethodInvokedInterceptor> methodInvokedInterceptors = GetInvokedInterceptors(method.Handler); MethodBuildContext context = new MethodBuildContext(serviceName, serviceType, serviceInstance, method.MethodType, method.RequestType, method.ResponseType, method.Handler, settings , Sort <IGrpcServerMethodInvokingInterceptor>(CompareInterceptor, new IEnumerable <IGrpcServerMethodInvokingInterceptor>[] { settings.InvokingInterceptors, classInvokingInterceptors, methodInvokingInterceptors }) , Sort <IGrpcServerMethodInvokedInterceptor>(CompareInterceptor, new IEnumerable <IGrpcServerMethodInvokedInterceptor>[] { settings.InvokedInterceptors, classInvokedInterceptors, methodInvokedInterceptors }) , Sort <IGrpcServerMethodExceptionHandler>(CompareInterceptor, new IEnumerable <IGrpcServerMethodExceptionHandler>[] { settings.ExceptionHandlers }) ); AddServiceMethod(builder, context); } return(builder.Build()); }
/// <summary> /// Register service methods to grpc /// </summary> /// <param name="method"></param> /// <param name="provider"></param> /// <param name="builder"></param> /// <param name="cfg"></param> public static void RegisterServiceMethodToGrpc(MethodInfo method, IServiceProvider provider, ServerServiceDefinition.Builder builder, GrpcServerConfiguration cfg) { // get service data var serviceType = method.DeclaringType; var serviceName = serviceType.Name; // get method data var methodName = method.Name; var requestType = method.GetParameters()[0].ParameterType; var responseType = method.ReturnType.GenericTypeArguments[0]; // create grpc method var grpcMethodFnc = typeof(GrpcMethodFactoryUtil).GetMethod(nameof(GrpcMethodFactoryUtil.CreateGrpcMethod)).MakeGenericMethod(requestType, responseType); var grpcMethod = grpcMethodFnc.Invoke(null, new object[] { serviceName, methodName }); // create grpc method handler var grpcMethodHandlerFnc = typeof(GrpcServerBuilder).GetMethod(nameof(GrpcServerBuilder.GenerateGrpcUnaryMethodHandler)). MakeGenericMethod(serviceType, requestType, responseType); var grpcMethodHandler = grpcMethodHandlerFnc.Invoke(null, new object[] { method }); // add method to services builder var addMethodFnc = typeof(GrpcServerBuilder).GetMethod(nameof(GrpcServerBuilder.AddGrpcMethodToDefinitionBuilder)). MakeGenericMethod(requestType, responseType, serviceType); addMethodFnc.Invoke(null, new object[] { provider, builder, grpcMethod, grpcMethodHandler, cfg }); }
/// <summary> /// サービスメソッドを追加します。 /// </summary> /// <typeparam name="TRequest">リクエストの型</typeparam> /// <typeparam name="TResponse">レスポンスの型</typeparam> /// <param name="builder">サービスビルダー</param> /// <param name="context">コンテキスト</param> private void AddServiceMethodGeneric <TRequest, TResponse>(ServerServiceDefinition.Builder builder, MethodBuildContext context) where TRequest : class where TResponse : class { Method <TRequest, TResponse> method = CreateServiceMethodFieldGeneric <TRequest, TResponse>(context); switch (method.Type) { case MethodType.Unary: builder.AddMethod <TRequest, TResponse>(method, CreateUnaryServerMethod <TRequest, TResponse>(context)); break; case MethodType.ClientStreaming: builder.AddMethod <TRequest, TResponse>(method, CreateClientStreamingServerMethod <TRequest, TResponse>(context)); break; case MethodType.ServerStreaming: builder.AddMethod <TRequest, TResponse>(method, CreateServerStreamingServerMethod <TRequest, TResponse>(context)); break; case MethodType.DuplexStreaming: builder.AddMethod <TRequest, TResponse>(method, CreateDuplexStreamingServerMethod <TRequest, TResponse>(context)); break; } }
/// <summary> /// サービスメソッド名を指定してサービス定義を生成します。 /// </summary> /// <param name="serviceName">サービス名</param> /// <param name="methodName">メソッド名</param> /// <returns>サービス定義</returns> public static ServerServiceDefinition BuildService(string serviceName, string methodName) { ServerServiceDefinition.Builder builder = ServerServiceDefinition.CreateBuilder(); builder.AddMethod <byte[], byte[]>(CreateMethod(serviceName, methodName), CreateHandler()); return(builder.Build()); }
private void AddMethod(ServerServiceDefinition.Builder serverServiceDefinitionBuilder, Method <TRequest, TResponse> method) { switch (method.Type) { case MethodType.Unary: var unaryHandler = _methodHandlerProvider.GetUnaryHandler(); serverServiceDefinitionBuilder.AddMethod(method, unaryHandler); break; case MethodType.ClientStreaming: var clientStreamingHandler = _methodHandlerProvider.GetClientStreamingServerHandler(); serverServiceDefinitionBuilder.AddMethod(method, clientStreamingHandler); break; case MethodType.ServerStreaming: var serverStreamingHandler = _methodHandlerProvider.GetServerStreamingServerHandler(); serverServiceDefinitionBuilder.AddMethod(method, serverStreamingHandler); break; case MethodType.DuplexStreaming: var duplexStreamingServerHandler = _methodHandlerProvider.GetDuplexStreamingServerHandler(); serverServiceDefinitionBuilder.AddMethod(method, duplexStreamingServerHandler); break; default: throw new ArgumentOutOfRangeException(); } }
public GrpcHostBuilder(IServiceProvider serviceProvider, ISerializer serializer, IOptions <RpcServerOptions> options) { this._serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); this._builder = ServerServiceDefinition.CreateBuilder(); this._serializer = serializer; this._options = options.Value; }
public static void AddServerStreamingMethod <T>(ServerServiceDefinition.Builder builder, Method <Void, T> method, Forwarder <T> forwarder) where T : class { builder.AddMethod(method, async(Void _, IServerStreamWriter <T> responseStream, ServerCallContext context) => { await forwarder.Subscribe(async reader => { while (context.CancellationToken.IsCancellationRequested == false) { var success = false; try { var x = await reader.ReadAsync(); await responseStream.WriteAsync(x); success = true; } catch (OperationCanceledException) { } if (success == false) { break; } } }); }); }
static void Main(string[] args) { ServerServiceDefinition.Builder builder = new ServerServiceDefinition.Builder(); Grpc.Core.Server server = new Server(); server.Services.Add(ServerServiceDefinition.Builder }
public SelfHostServiceMethodBinder( IMarshallerFactory marshallerFactory, Func <TService> serviceFactory, ServerServiceDefinition.Builder builder) { MarshallerFactory = marshallerFactory; _serviceFactory = serviceFactory; _builder = builder; }
/// <summary> /// /// </summary> protected void AddMethods(object serviceInstance) { string serviceName = "TestService"; TestService service = new TestService(); foreach (RpcMethodHandlerInfo methodHandler in RpcReflection.EnumerateServiceMethods(typeof(TestService), false)) { m_Service = RpcReflection.AddMethod(m_Service, serviceName, methodHandler, MessagePackMarshaller.Current, service); } }
/// <summary> /// Creates the RPC method description. /// </summary> /// <param name="builder">The service builder.</param> /// <param name="serviceName">The service name.</param> /// <param name="handler">The method information.</param> /// <param name="marshallerFactory">The factory of the marshaller.</param> /// <param name="serviceInstance">The service instance.</param> /// <returns>The method description.</returns> public static ServerServiceDefinition.Builder AddMethod(ServerServiceDefinition.Builder builder, string serviceName, RpcMethodHandlerInfo handler, IRpcMarshallerFactory marshallerFactory, object serviceInstance) { if (handler.RequestType.IsClass && handler.ResponseType.IsClass) { MethodInfo m = typeof(RpcReflection).GetMethod("AddMethodCore", BindingFlags.Static | BindingFlags.NonPublic); return((ServerServiceDefinition.Builder)m.MakeGenericMethod(new Type[] { handler.RequestType, handler.ResponseType }).Invoke(null, new object[] { builder, serviceName, handler, marshallerFactory, serviceInstance })); } else { MethodInfo m = typeof(RpcReflection).GetMethod("AddStructMethodCore", BindingFlags.Static | BindingFlags.NonPublic); return((ServerServiceDefinition.Builder)m.MakeGenericMethod(new Type[] { handler.RequestType, handler.ResponseType }).Invoke(null, new object[] { builder, serviceName, handler, marshallerFactory, serviceInstance })); } }
internal void RegisterHandler(ServerServiceDefinition.Builder builder) { var method = new Method <byte[], byte[]>(this.MethodType, this.ServiceName, this.MethodName, MagicOnionMarshallers.ThroughMarshaller, MagicOnionMarshallers.ThroughMarshaller); switch (this.MethodType) { case MethodType.Unary: { var genericMethod = this.GetType() .GetMethod(nameof(UnaryServerMethod), BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(RequestType, UnwrappedResponseType); var handler = (UnaryServerMethod <byte[], byte[]>)genericMethod.CreateDelegate(typeof(UnaryServerMethod <byte[], byte[]>), this); builder.AddMethod(method, handler); } break; case MethodType.ClientStreaming: { var genericMethod = this.GetType() .GetMethod(nameof(ClientStreamingServerMethod), BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(RequestType, UnwrappedResponseType); var handler = (ClientStreamingServerMethod <byte[], byte[]>)genericMethod.CreateDelegate(typeof(ClientStreamingServerMethod <byte[], byte[]>), this); builder.AddMethod(method, handler); } break; case MethodType.ServerStreaming: { var genericMethod = this.GetType() .GetMethod(nameof(ServerStreamingServerMethod), BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(RequestType, UnwrappedResponseType); var handler = (ServerStreamingServerMethod <byte[], byte[]>)genericMethod.CreateDelegate(typeof(ServerStreamingServerMethod <byte[], byte[]>), this); builder.AddMethod(method, handler); } break; case MethodType.DuplexStreaming: { var genericMethod = this.GetType() .GetMethod(nameof(DuplexStreamingServerMethod), BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(RequestType, UnwrappedResponseType); var handler = (DuplexStreamingServerMethod <byte[], byte[]>)genericMethod.CreateDelegate(typeof(DuplexStreamingServerMethod <byte[], byte[]>), this); builder.AddMethod(method, handler); } break; default: throw new InvalidOperationException("Unknown RegisterType:" + this.MethodType); } }
private static void AddMethod <TRequest, TResult>(ServerServiceDefinition.Builder builder, string name, Func <TRequest, TResult> handler) where TRequest : class where TResult : class { var method = new Method <TRequest, TResult>( MethodType.Unary, nameof(ICustomerData), name, new Marshaller <TRequest>(MessagePackSerializer.Serialize, MessagePackSerializer.Deserialize <TRequest>), new Marshaller <TResult>(MessagePackSerializer.Serialize, MessagePackSerializer.Deserialize <TResult>)); builder.AddMethod(method, (request, context) => { var result = handler(request); return(Task.FromResult(result)); }); }
/// <summary> /// Add grpc method to definition builder /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <typeparam name="TService"></typeparam> /// <param name="provider"></param> /// <param name="builder"></param> /// <param name="method"></param> /// <param name="handler"></param> /// <param name="cfg"></param> public static void AddGrpcMethodToDefinitionBuilder <TRequest, TResponse, TService>( IServiceProvider provider, ServerServiceDefinition.Builder builder, Method <TRequest, TResponse> method, Func <TService, TRequest, CancellationToken, Task <TResponse> > handler, GrpcServerConfiguration cfg) where TService : class where TRequest : class where TResponse : class { // get host stats var stats = provider.GetServices <GrpcHost>().FirstOrDefault(h => h.Name == cfg.Name)?.Stats; // add method builder.AddMethod(method, async(req, responseStream, context) => { await RequestHandler.HandleRequest <TRequest, TResponse, TService>(provider, req, handler, cfg.Name, method.Name, context, responseStream); }); }
/// <summary> /// 注册服务方法 /// </summary> public void RegisterMethod(ServerServiceDefinition.Builder builder) { builder.AddMethod(this.BuildMethod <AddDelThrottleRQ, CmdRS>("AddDelThrottle", "grpc", Consts.BaseServiceName), AddDelThrottle); builder.AddMethod(this.BuildMethod <AddDelSaveResponseEnableRQ, CmdRS>("AddDelSaveResponseEnable", "grpc", Consts.BaseServiceName), AddDelSaveResponseEnable); }
/// <summary> /// Creates the RPC method description. /// </summary> /// <typeparam name="TRequest">The type of the request.</typeparam> /// <typeparam name="TResponse">The type of the response.</typeparam> /// <param name="builder">The service builder.</param> /// <param name="serviceName">The service name.</param> /// <param name="handler">The method information.</param> /// <param name="marshallerFactory">The factory of the marshaller.</param> /// <param name="serviceInstance">The service instance.</param> /// <returns>The method description.</returns> private static ServerServiceDefinition.Builder AddStructMethodCore <TRequest, TResponse>(ServerServiceDefinition.Builder builder, string serviceName, RpcMethodHandlerInfo handler, IRpcMarshallerFactory marshallerFactory, object serviceInstance) { Method <TRequest, TResponse> method = new Method <TRequest, TResponse>(handler.MethodType, serviceName, handler.Handler.Name, marshallerFactory.GetMarshaller <TRequest>(), marshallerFactory.GetMarshaller <TResponse>()); switch (handler.MethodType) { case MethodType.Unary: return(builder.AddStructMethod(method, (StructUnaryServerMethod <TRequest, TResponse>)handler.Handler.CreateDelegate(typeof(StructUnaryServerMethod <TRequest, TResponse>), serviceInstance))); case MethodType.ClientStreaming: return(builder.AddStructMethod(method, (StructClientStreamingServerMethod <TRequest, TResponse>)handler.Handler.CreateDelegate(typeof(StructClientStreamingServerMethod <TRequest, TResponse>), serviceInstance))); case MethodType.ServerStreaming: return(builder.AddStructMethod(method, (StructServerStreamingServerMethod <TRequest, TResponse>)handler.Handler.CreateDelegate(typeof(StructServerStreamingServerMethod <TRequest, TResponse>), serviceInstance))); case MethodType.DuplexStreaming: return(builder.AddStructMethod(method, (StructDuplexStreamingServerMethod <TRequest, TResponse>)handler.Handler.CreateDelegate(typeof(StructDuplexStreamingServerMethod <TRequest, TResponse>), serviceInstance))); default: return(builder); } }
/// <summary> /// 自动注册服务方法 /// </summary> /// <param name="srv"></param> /// <param name="builder"></param> /// <param name="package"></param> /// <param name="serviceName"></param> public static void AutoRegisterMethod(IGrpcService srv, ServerServiceDefinition.Builder builder, string package = null, string serviceName = null) { var methods = srv.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (var method in methods) { if (!method.ReturnType.Name.StartsWith("Task")) { continue; } var parameters = method.GetParameters(); if (parameters[parameters.Length - 1].ParameterType != typeof(ServerCallContext) || method.CustomAttributes.Any(x => x.AttributeType == typeof(NotGrpcMethodAttribute))) { continue; } Type inputType = parameters[0].ParameterType; Type inputType2 = parameters[1].ParameterType; Type outputType = method.ReturnType.IsGenericType ? method.ReturnType.GenericTypeArguments[0] : method.ReturnType; var addMethod = unaryAddMethod; var serverMethodType = typeof(UnaryServerMethod <,>); var methodType = MethodType.Unary; var reallyInputType = inputType; var reallyOutputType = outputType; //非一元方法 if ((inputType.IsGenericType || inputType2.IsGenericType)) { if (inputType.Name == "IAsyncStreamReader`1") { reallyInputType = inputType.GenericTypeArguments[0]; if (inputType2.Name == "IServerStreamWriter`1")//双向流 { addMethod = duplexStreamingAddMethod; methodType = MethodType.DuplexStreaming; serverMethodType = typeof(DuplexStreamingServerMethod <,>); reallyOutputType = inputType2.GenericTypeArguments[0]; } else//客户端流 { addMethod = clientStreamingAddMethod; methodType = MethodType.ClientStreaming; serverMethodType = typeof(ClientStreamingServerMethod <,>); } } else if (inputType2.Name == "IServerStreamWriter`1")//服务端流 { addMethod = serverStreamingAddMethod; methodType = MethodType.ServerStreaming; serverMethodType = typeof(ServerStreamingServerMethod <,>); reallyOutputType = inputType2.GenericTypeArguments[0]; } } var buildMethodResult = buildMethod.MakeGenericMethod(reallyInputType, reallyOutputType) .Invoke(null, new object[] { srv, method.Name, package, serviceName, methodType }); Delegate serverMethodDelegate = method.CreateDelegate(serverMethodType .MakeGenericType(reallyInputType, reallyOutputType), method.IsStatic ? null : srv); addMethod.MakeGenericMethod(reallyInputType, reallyOutputType).Invoke(builder, new[] { buildMethodResult, serverMethodDelegate }); } }
public ServerBuilder() { builder = ServerServiceDefinition.CreateBuilder(); }
/// <summary> /// 注册grpc服务方法 /// </summary> public void RegisterMethod(ServerServiceDefinition.Builder builder) { builder.AddMethod(this.BuildMethod <InfoRQ, InfoRS>("Info", "grpc", Consts.BaseServiceName), Info); builder.AddMethod(this.BuildMethod <MethodInfoRQ, MethodInfoRS>("MethodInfo", "grpc", Consts.BaseServiceName), MethodInfo); builder.AddMethod(this.BuildMethod <MethodInvokeRQ, MethodInvokeRS>("MethodInvoke", "grpc", Consts.BaseServiceName), MethodInvoke); }
public GrpcHostBuilder(IServiceProvider appServices) { _appServices = appServices; _builder = ServerServiceDefinition.CreateBuilder(); }
public void RegisterMethod(ServerServiceDefinition.Builder builder) { builder.AddMethod(this.BuildMethod <AddRequest, IntMessage>("Add", null), Add); builder.AddMethod(this.BuildMethod <SubRequest, IntMessage>("Sub", null), Sub); builder.AddMethod(this.BuildMethod <SumRequest, IntMessage>("Sum", null, mType: MethodType.ClientStreaming), Sum); }
/// <summary> /// Adds a definition for a client streaming method without type restrictions. /// </summary> /// <typeparam name="TRequest">The type of the request.</typeparam> /// <typeparam name="TResponse">The type of the response.</typeparam> /// <param name="builder"></param> /// <param name="method"></param> /// <param name="handler"></param> /// <returns></returns> public static ServerServiceDefinition.Builder AddStructMethod <TRequest, TResponse>(this ServerServiceDefinition.Builder builder, Method <TRequest, TResponse> method, StructClientStreamingServerMethod <TRequest, TResponse> handler) { async Task <byte[]> func(IAsyncStreamReader <byte[]> requestStream, ServerCallContext context) { TResponse response = await handler( requestStream.Convert(method.RequestMarshaller.Deserializer) , context ).ConfigureAwait(false); return(method.ResponseMarshaller.Serializer(response)); }; return(builder.AddMethod(s_StructMethodCache.GetMethod(method), func)); }
/// <summary> /// サービスメソッドを追加します。 /// </summary> /// <param name="builder">サービスビルダー</param> /// <param name="context">コンテキスト</param> private void AddServiceMethod(ServerServiceDefinition.Builder builder, MethodBuildContext context) { typeof(GrpcServiceBuilder).GetMethod("AddServiceMethodGeneric", BindingFlags.Instance | BindingFlags.NonPublic) .MakeGenericMethod(new Type[] { context.RequestType, context.ResponseType }) .Invoke(this, new object[] { builder, context }); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="method"></param> /// <param name="handler"></param> protected void AddStructMethod <TRequest, TResponse>(Method <TRequest, TResponse> method, StructUnaryServerMethod <TRequest, TResponse> handler) { m_Service = m_Service.AddStructMethod(method, handler); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="method"></param> /// <param name="handler"></param> protected void AddMethod <TRequest, TResponse>(Method <TRequest, TResponse> method, DuplexStreamingServerMethod <TRequest, TResponse> handler) where TRequest : class where TResponse : class { m_Service = m_Service.AddMethod(method, handler); }
/// <summary> /// Adds a definition for a duplex streaming method without type restrictions. /// </summary> /// <typeparam name="TRequest">The type of the request.</typeparam> /// <typeparam name="TResponse">The type of the response.</typeparam> /// <param name="builder"></param> /// <param name="method"></param> /// <param name="handler"></param> /// <returns></returns> public static ServerServiceDefinition.Builder AddStructMethod <TRequest, TResponse>(this ServerServiceDefinition.Builder builder, Method <TRequest, TResponse> method, StructDuplexStreamingServerMethod <TRequest, TResponse> handler) { Task func(IAsyncStreamReader <byte[]> requestStream, IServerStreamWriter <byte[]> responseStream, ServerCallContext context) { return(handler( requestStream.Convert(bytes => method.RequestMarshaller.Deserializer(bytes)) , responseStream.ConvertResponse(method.ResponseMarshaller.Serializer) , context )); }; return(builder.AddMethod(s_StructMethodCache.GetMethod(method), func)); }
/// <summary> /// /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="method"></param> /// <param name="handler"></param> protected void AddStructMethod <TRequest, TResponse>(Method <TRequest, TResponse> method, StructDuplexStreamingServerMethod <TRequest, TResponse> handler) { m_Service = m_Service.AddStructMethod(method, handler); }