/// <summary> /// <para>add MagicOnion service to generic host with specific types or assemblies</para> /// </summary> /// <remarks>you must not pass null to options</remarks> public static IHostBuilder UseMagicOnion(this IHostBuilder hostBuilder, IEnumerable <ServerPort> ports, MagicOnionOptions options, IEnumerable <Type> types = null, Assembly[] searchAssemblies = null, IEnumerable <ChannelOption> channelOptions = null) { return(hostBuilder.ConfigureServices((ctx, services) => { // should transient or singleton? // in AddHostedService<T> implementation, singleton is used // https://github.com/aspnet/Extensions/blob/8b2482fa68c548e904e4aa1ae38a29c72dcd32a5/src/Hosting/Abstractions/src/ServiceCollectionHostedServiceExtensions.cs#L18 services.AddSingleton <IHostedService, MagicOnionServerService>(serviceProvider => { return new MagicOnionServerService( new MagicOnionServerServiceOptions() { ChannelOptions = channelOptions, MagicOnionOptions = options, Ports = ports, SearchAssemblies = searchAssemblies, Types = types } ); }); })); }
public override void OnApplicationInitialization(CafApplicationContext context) { var options = new MagicOnionOptions(); options.IsReturnExceptionStackTraceInErrorDetail = true; options.ServiceLocator = new MicrosoftExtensionsServiceLocator(context.ServiceProvider, options);//new ServiceLocatorBridge(factory); options.MagicOnionServiceActivator = new MicrosoftExtensionsMagicOnionServiceActivator(); MagicOnionServiceDefinition serviceDefine = null; var config = context.ServiceProvider.GetRequiredService <IGrpcServerConfiguration>(); var generator = context.ServiceProvider.GetRequiredService <IGrpcServiceGenerator>(); generator.GeneraterProxyService();//创建MagicOnion grpc 代理程序集 config.GrpcAssemblies = config.GrpcAssemblies.Append(generator.DynamicAssembly).ToList(); config.GrpcAssemblies = config.GrpcAssemblies.Append(generator.DynamicInterfaceAssembly).ToList(); if (config.GrpcAssemblies != null) { serviceDefine = MagicOnionEngine.BuildServerServiceDefinition(config.GrpcAssemblies.ToArray(), options); } var packageMagicOnionServerService = new PackageMagicOnionServerService(serviceDefine, new[] { new ServerPort(config.GrpcBindAddress, config.GrpcBindPort, ServerCredentials.Insecure) }, null); packageMagicOnionServerService.StartAsync(CancellationToken.None); }
static void Main(string[] args) { //gRPCサーバーのAddress・Port設定 var serverPort = new ServerPort("localhost", 1234, ServerCredentials.Insecure); //ロガーとかの設定 var magicOnionOptions = new MagicOnionOptions(isReturnExceptionStackTraceInErrorDetail: true) { //todo:settings }; //サービスクラスの実装が別アセンブリの場合はアセンブリを指定する var searchAssembly = new[] { typeof(Sample.MagicOnion.Server.Calculator).Assembly }; var server = new Grpc.Core.Server() { Ports = { serverPort }, Services = { //MagicOnionサービス MagicOnionEngine.BuildServerServiceDefinition(searchAssembly, magicOnionOptions), //PureGrpcサービス PureGrpc.Definitions.Calculator.BindService(new Sample.PureGrpc.Server.CalculatorImpl()), PureGrpc.Definitions.Health.BindService(new Sample.PureGrpc.Server.HealthImpl()), } }; server.Start(); Console.ReadLine(); }
/// <summary> /// 初始化 Grpc 服务 /// </summary> /// <param name="config">Grpc 配置项</param> private void InitializeGrpcServer(IGrpcServerConfiguration config) { var options = new MagicOnionOptions(); options.IsReturnExceptionStackTraceInErrorDetail = true; var serviceLocator = new CasteWindsorServiceLocatorBridge(IocManager); options.ServiceLocator = serviceLocator; // 构建 gRpc 服务。 MagicOnionServiceDefinition serviceDefine = null; if (config.GrpcAssemblies != null) { serviceDefine = MagicOnionEngine.BuildServerServiceDefinition(config.GrpcAssemblies.ToArray(), options); } // 注入 gRpc 服务到 IoC 容器当中。 IocManager.IocContainer.Register(Component.For <MagicOnionServiceDefinition>().Instance(serviceDefine).LifestyleSingleton()); IocManager.IocContainer.Register(Component.For <IHostedService>().Instance(new PackageMagicOnionServerService(serviceDefine, new[] { new ServerPort(config.GrpcBindAddress, config.GrpcBindPort, ServerCredentials.Insecure) }, null)).LifestyleSingleton()); AsyncHelper.RunSync(() => IocManager.Resolve <IHostedService>().StartAsync(CancellationToken.None)); }
/// <summary>add MagicOnion service to generic host from all assemblies.</summary> public static IHostBuilder UseMagicOnion(this IHostBuilder hostBuilder, ServerPort ports, MagicOnionOptions options, IEnumerable <ChannelOption> channelOptions = null) { return(UseMagicOnion(hostBuilder, new[] { ports }, options, channelOptions: channelOptions)); }
static async Task Main(string[] _) { //gRPCサーバーのAddress・Port設定 var serverPort = new ServerPort("localhost", 1234, ServerCredentials.Insecure); //ロガーとかの設定 var magicOnionOptions = new MagicOnionOptions(isReturnExceptionStackTraceInErrorDetail: true) { //todo:settings }; //サービスクラスの実装が別アセンブリの場合はアセンブリを指定する var searchAssembly = new[] { typeof(Sample.MagicOnion.Server.Calculator).Assembly }; //MagicOnion.Hostingを使用する場合 { await MagicOnionHost.CreateDefaultBuilder() .UseMagicOnion(searchAssembly, magicOnionOptions, serverPort) .RunConsoleAsync(); } //自前でgRPC.Core.Serverを実行する場合 { var server = new Grpc.Core.Server() { Ports = { serverPort }, Services = { MagicOnionEngine.BuildServerServiceDefinition(searchAssembly, magicOnionOptions) } }; server.Start(); Console.ReadLine(); } }
public override void OnApplicationInitialization(ApplicationInitializationContext context) { using (var scope = context.ServiceProvider.CreateScope()) { var magicOnionOption = new MagicOnionOptions(); magicOnionOption.IsReturnExceptionStackTraceInErrorDetail = false; } }
public StreamingHubHandlerOptions(MagicOnionOptions options) { GlobalStreamingHubFilters = options.GlobalStreamingHubFilters; Logger = options.MagicOnionLogger; FormatterResolver = options.FormatterResolver; ServiceLocator = options.ServiceLocator; ServiceActivator = options.MagicOnionServiceActivator; }
public StreamingHubHandlerOptions(MagicOnionOptions options) { GlobalStreamingHubFilters = options.GlobalStreamingHubFilters; Logger = options.MagicOnionLogger; SerializerOptions = options.SerializerOptions; ServiceLocator = options.ServiceLocator; ServiceActivator = options.MagicOnionServiceActivator; }
public static Server StartServer(this ServerPort serverPort) { var options = new MagicOnionOptions { IsReturnExceptionStackTraceInErrorDetail = true }; var service = MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ReactiveLoggerHubService).GetTypeInfo().Assembly }, options); var server = new Server { Services = { service.ServerServiceDefinition }, Ports = { serverPort } }; server.Start(); return(server); }
/// <summary> /// <para>add MagicOnion service to generic host with specific types or assemblies</para> /// </summary> /// <remarks>you must not pass null to options</remarks> public static IHostBuilder UseMagicOnion(this IHostBuilder hostBuilder, IEnumerable <ServerPort> ports, MagicOnionOptions options, IEnumerable <Type> types = null, Assembly[] searchAssemblies = null, IEnumerable <ChannelOption> channelOptions = null) { return(hostBuilder.ConfigureServices((ctx, services) => { var serviceLocator = new ServiceLocatorBridge(services); options.ServiceLocator = serviceLocator; // replace it. // build immediately(require register service before create it). MagicOnionServiceDefinition serviceDefinition; if (searchAssemblies != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(searchAssemblies, options); } else if (types != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(types, options); } else { if (options != null) { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(options); } else { serviceDefinition = MagicOnionEngine.BuildServerServiceDefinition(); } } // store service definition services.AddSingleton <MagicOnionServiceDefinition>(serviceDefinition); // should transient or singleton? // in AddHostedService<T> implementation, singleton is used // https://github.com/aspnet/Extensions/blob/8b2482fa68c548e904e4aa1ae38a29c72dcd32a5/src/Hosting/Abstractions/src/ServiceCollectionHostedServiceExtensions.cs#L18 services.AddSingleton <IHostedService, MagicOnionServerService>(serviceProvider => { serviceLocator.provider = serviceProvider; // set built provider. return new MagicOnionServerService(serviceDefinition, ports, channelOptions); }); })); }
protected virtual void PrepareServer() { var options = CreateMagicOnionOptions(); var service = BuildServerServiceDefinition(options); var port = RandomProvider.ThreadRandom.Next(10000, 30000); var serverPort = new ServerPort("localhost", port, ServerCredentials.Insecure); server = new global::Grpc.Core.Server { Services = { service.ServerServiceDefinition }, Ports = { serverPort } }; server.Start(); Options = options; ServerPort = serverPort; DefaultChannel = new Channel(serverPort.Host, serverPort.Port, ChannelCredentials.Insecure); }
public static IHostBuilder UseMagicOnionHost(this IHostBuilder builder, IApiInfo apiInfo, Assembly[] searchAssemblies = null, MagicOnionOptions options = null, IEnumerable <ChannelOption> channelOptions = null) { if (searchAssemblies == null) { searchAssemblies = new[] { Assembly.GetEntryAssembly() }; } return(MagicOnion.Hosting.MagicOnionServerServiceExtension.UseMagicOnion(builder, new[] { new ServerPort(apiInfo.BindAddress, apiInfo.BindPort, ServerCredentials.Insecure) }, options ?? new MagicOnionOptions(), null, searchAssemblies, channelOptions)); }
public ServerFixture() { var options = new MagicOnionOptions { IsReturnExceptionStackTraceInErrorDetail = true }; var service = MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ServerFixture).GetTypeInfo().Assembly }, options); var port = RandomProvider.ThreadRandom.Next(10000, 30000); var serverPort = new ServerPort("localhost", port, ServerCredentials.Insecure); server = new global::Grpc.Core.Server { Services = { service.ServerServiceDefinition }, Ports = { serverPort } }; server.Start(); ServerPort = serverPort; DefaultChannel = new Channel(serverPort.Host, serverPort.Port, ChannelCredentials.Insecure); }
/// <summary> /// <para>add MagicOnion service to generic host with specific types or assemblies</para> /// </summary> /// <remarks>you must not pass null to options</remarks> public static IHostBuilder UseMagicOnion(this IHostBuilder hostBuilder, IEnumerable <ServerPort> ports, MagicOnionOptions options, IEnumerable <Type> types = null, Assembly[] searchAssemblies = null, IEnumerable <ChannelOption> channelOptions = null) { if (ports == null) { throw new ArgumentNullException(nameof(ports)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return(hostBuilder.ConfigureServices((hostContext, services) => { // Register a MagicOnion hosted service. services.AddSingleton <IHostedService>(serviceProvider => { var logger = serviceProvider.GetService <ILoggerFactory>().CreateLogger <MagicOnionServerService>(); var serviceDefinition = serviceProvider.GetService <MagicOnionHostedServiceDefinition>(); return CreateMagicOnionHostedService(logger, ports, serviceDefinition.ServiceDefinition, channelOptions); }); // Register MagicOnionServiceDefinition (when using HttpGateway, it requests MagicOnionServiceDefinition via host's ServiceProvider) services.AddMagicOnionHostedServiceDefinition(Options.DefaultName, types, searchAssemblies); // Options: Hosting startup configuration services.AddOptions <MagicOnionHostingOptions>(Options.DefaultName) .Configure(hostingOptions => { hostingOptions.Service = options; }); })); }
static void Main(string[] args) { // GrpcのLogging機構を使う GrpcEnvironment.SetLogger(new ConsoleLogger()); GrpcEnvironment.Logger.Info("Server startup! ================================="); // MaginOnion側のログを gRPC のログに流し込む設定 // ※JSON形式でデータダンプする var logger = new MagicOnionLogToGrpcLoggerWithDataDump(); var options = new MagicOnionOptions(true) { MagicOnionLogger = logger }; //--- ここで動的にアセンブリを解釈し、通信されてきたデータと API 本体とのマップを作る var service = MagicOnionEngine.BuildServerServiceDefinition(options); //--- API を公開する IP / Port / 認証情報などを決定し、gRPC サーバーを起動 var port = new ServerPort("localhost", 12345, ServerCredentials.Insecure); var server = new Server(new[] { new ChannelOption(ChannelOptions.MaxReceiveMessageLength, int.MaxValue), new ChannelOption(ChannelOptions.MaxSendMessageLength, int.MaxValue), }) { Services = { service }, Ports = { port }, }; server.Start(); GrpcEnvironment.Logger.Info("Server started"); //--- exe が終了しちゃわないように Console.ReadLine(); GrpcEnvironment.Logger.Info("Server closed. ---------------------------------"); }
public ServiceLocatorTest(ServiceLocatorTestServerFixture serverFixture) { channel = serverFixture.DefaultChannel; options = serverFixture.Options; }
protected virtual MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options) => MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ServerFixture).GetTypeInfo().Assembly }, options);
/// <summary> /// Search MagicOnion service from all assemblies. /// </summary> public static MyServerServiceDefinition Build(MagicOnionOptions options) { return(BuildServerServiceDefinition(AppDomain.CurrentDomain.GetAssemblies(), options)); }
static async Task Main(string[] args) { // ServiceLocatorHelper.CreateService<UnaryService, ICalcSerivce>(null); const string GrpcHost = "localhost"; Console.WriteLine("Server:::"); //Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG"); //Environment.SetEnvironmentVariable("GRPC_TRACE", "all"); Environment.SetEnvironmentVariable("SETTINGS_MAX_HEADER_LIST_SIZE", "1000000"); GrpcEnvironment.SetLogger(new ConsoleLogger()); var options = new MagicOnionOptions(true) { //MagicOnionLogger = new MagicOnionLogToGrpcLogger(), MagicOnionLogger = new MagicOnionLogToGrpcLoggerWithNamedDataDump(), GlobalFilters = new MagicOnionFilterAttribute[] { }, EnableCurrentContext = true, DisableEmbeddedService = true, }; var magicOnionHost = MagicOnionHost.CreateDefaultBuilder(useSimpleConsoleLogger: true) .UseMagicOnion(options, new ServerPort("localhost", 12345, ServerCredentials.Insecure)) .UseConsoleLifetime() .Build(); // test webhost // NuGet: Microsoft.AspNetCore.Server.Kestrel var webHost = new WebHostBuilder() .ConfigureServices(collection => { // Add MagicOnionServiceDefinition for reference from Startup. collection.AddSingleton <MagicOnionServiceDefinition>(magicOnionHost.Services.GetService <MagicOnionServiceDefinition>()); }) .UseKestrel() .UseStartup <Startup>() .UseUrls("http://localhost:5432") .Build(); await Task.WhenAll(webHost.RunAsync(), magicOnionHost.RunAsync()); //webHost.Run(); //Console.ReadLine(); //{ // var channel = new Channel("localhost:12345", ChannelCredentials.Insecure); // var client = StreamingHubClient.Connect<IChatHub, IMessageReceiver2>(channel, new Receiver()); // Console.WriteLine("Call to Server"); // await client.JoinAsync("me", "foo"); // await Task.WhenAll( // client.SendMessageAsync("a"), // client.SendMessageAsync("b"), // client.SendMessageAsync("c"), // client.SendMessageAsync("d"), // client.SendMessageAsync("e")); // Console.WriteLine("OK to Send"); // await client.DisposeAsync(); // await channel.ShutdownAsync(); //} }
static async Task Main(string[] args) { //添加 json 文件路径 var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); //创建配置根对象 var Configuration = builder.Build(); //Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG"); //Environment.SetEnvironmentVariable("GRPC_TRACE", "all"); Environment.SetEnvironmentVariable("SETTINGS_MAX_HEADER_LIST_SIZE", "1000000"); GrpcEnvironment.SetLogger(new ConsoleLogger()); var options = new MagicOnionOptions(true) { MagicOnionLogger = new MagicOnionLogToGrpcLoggerWithNamedDataDump(), GlobalFilters = new MagicOnionFilterAttribute[] { }, EnableCurrentContext = true, DefaultGroupRepositoryFactory = new ConcurrentDictionaryGroupRepositoryFactory(), DisableEmbeddedService = true, }; var conn = ConnectionMultiplexer.Connect(Configuration["RedisConn"]); options.ServiceLocator.Register(conn); options.ServiceLocator.Register(MessagePackSerializer.DefaultResolver); options.ServiceLocator.Register <IMagicOnionLogger>(new NullMagicOnionLogger()); //IServiceCollection services = new ServiceCollection(); //services.AddTransient<ISomeService>(sp => new FooService(5)); //services.AddAutoMapper(typeof(Source)); //var provider = services.BuildServiceProvider(); //using (var scope = provider.CreateScope()) //{ // var mapper = scope.ServiceProvider.GetService<IMapper>(); // foreach (var typeMap in mapper.ConfigurationProvider.GetAllTypeMaps()) // { // Console.WriteLine($"{typeMap.SourceType.Name} -> {typeMap.DestinationType.Name}"); // } // foreach (var service in services) // { // Console.WriteLine(service.ServiceType + " - " + service.ImplementationType); // } // var dest = mapper.Map<Dest2>(new Source2()); // Console.WriteLine(dest.ResolvedValue); //} var magicOnionHost = MagicOnionHost.CreateDefaultBuilder(useSimpleConsoleLogger: true) .ConfigureServices((ctx, services) => { services.Configure <MongoAppSetting>(x => { x.MongoConn = Configuration["MongoConn"].ToString(); x.MongoDbDatabase = Configuration["MongoDbDatabase"].ToString(); }); services.AddAutoMapper((collect, cfg) => { cfg.AddProfile <MappingProfile>(); }, AppDomain.CurrentDomain.GetAssemblies()); services.Add(new ServiceDescriptor(typeof(IMapper), sp => new Mapper(sp.GetRequiredService <AutoMapper.IConfigurationProvider>(), sp.GetService), ServiceLifetime.Transient)); services.AddSingleton <MongoDbContext>(); services.AddScoped <IUserRepository, UserRepository>(); }) .UseMagicOnion(options, new ServerPort(Configuration["GrpcService:IP"], Convert.ToInt32(Configuration["GrpcService:Port"]), ServerCredentials.Insecure)) .UseConsoleLifetime() .Build(); var webHost = new WebHostBuilder() .ConfigureServices(collection => { // Add MagicOnionServiceDefinition for reference from Startup. collection.AddSingleton <MagicOnionServiceDefinition>(magicOnionHost.Services .GetService <MagicOnionServiceDefinition>()); }) .UseKestrel() .UseStartup <Startup>() .UseUrls("http://localhost:5432") .Build(); await Task.WhenAll(webHost.RunAsync(), magicOnionHost.RunAsync()); }
protected override void ConfigureMagicOnion(MagicOnionOptions options) { }
//private static AsyncLocal<IServiceProvider> dics = new AsyncLocal<IServiceProvider>(); //public static IServiceProvider current => dics.Value; public ServiceLocatorBridge(IServiceScopeFactory serviceProvider, MagicOnionOptions magicOnionOptions) { _serviceProvider = serviceProvider; }
protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options) { return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(FilterConstructorInjectionTester) }, options)); }
protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options) { return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ConfigurationChange) }, options)); }
public StreamingHubHandlerOptions(MagicOnionOptions options) { GlobalStreamingHubFilters = options.GlobalStreamingHubFilters; SerializerOptions = options.SerializerOptions; }
protected abstract MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options);
protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options) { options.DefaultGroupRepositoryFactory = new ImmutableArrayGroupRepositoryFactory(); return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(StreamingHubBroadcastTestHub) }, options)); }
public StreamingHubHandler(MagicOnionOptions options, Type classType, MethodInfo methodInfo) { var hubInterface = classType.GetInterfaces().First(x => x.GetTypeInfo().IsGenericType&& x.GetGenericTypeDefinition() == typeof(IStreamingHub <,>)).GetGenericArguments()[0]; var interfaceMethod = hubInterface.GetMethods().First(x => x.Name == methodInfo.Name); this.HubType = classType; this.HubName = hubInterface.Name; this.MethodInfo = methodInfo; // Validation for Id if (methodInfo.GetCustomAttribute <MethodIdAttribute>() != null) { throw new InvalidOperationException($"Hub Implementation can not add [MethodId], you should add hub `interface`. {classType.Name}/{methodInfo.Name}"); } this.MethodId = interfaceMethod.GetCustomAttribute <MethodIdAttribute>()?.MethodId ?? FNV1A32.GetHashCode(interfaceMethod.Name); this.UnwrappedResponseType = UnwrapResponseType(methodInfo); this.resolver = options.FormatterResolver; var parameters = methodInfo.GetParameters(); if (RequestType == null) { this.RequestType = MagicOnionMarshallers.CreateRequestTypeAndSetResolver(classType.Name + "/" + methodInfo.Name, parameters, ref resolver); } this.AttributeLookup = classType.GetCustomAttributes(true) .Concat(methodInfo.GetCustomAttributes(true)) .Cast <Attribute>() .ToLookup(x => x.GetType()); this.filters = options.GlobalStreamingHubFilters .Concat(classType.GetCustomAttributes <StreamingHubFilterAttribute>(true)) .Concat(methodInfo.GetCustomAttributes <StreamingHubFilterAttribute>(true)) .OrderBy(x => x.Order) .ToArray(); // validation filter if (methodInfo.GetCustomAttribute <MagicOnionFilterAttribute>(true) != null) { throw new InvalidOperationException($"StreamingHub method can not add [MagicOnionFilter], you should add [StreamingHubFilter]. {classType.Name}/{methodInfo.Name}"); } this.toStringCache = HubName + "/" + MethodInfo.Name; this.getHashCodeCache = HubName.GetHashCode() ^ MethodInfo.Name.GetHashCode() << 2; // ValueTask (StreamingHubContext context) => // { // T request = LZ4MessagePackSerializer.Deserialize<T>(context.Request, context.FormatterResolver); // Task<T> result = ((HubType)context.HubInstance).Foo(request); // return WriteInAsyncLockInTaskWithMessageId(result) || return new ValueTask(result) // } try { var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; var contextArg = Expression.Parameter(typeof(StreamingHubContext), "context"); var requestArg = Expression.Parameter(RequestType, "request"); var getResolver = Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("FormatterResolver", flags)); var contextRequest = Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("Request", flags)); var getInstanceCast = Expression.Convert(Expression.Property(contextArg, typeof(StreamingHubContext).GetProperty("HubInstance", flags)), HubType); var callDeserialize = Expression.Call(messagePackDeserialize.MakeGenericMethod(RequestType), contextRequest, getResolver); var assignRequest = Expression.Assign(requestArg, callDeserialize); Expression[] arguments = new Expression[parameters.Length]; if (parameters.Length == 1) { arguments[0] = requestArg; } else { for (int i = 0; i < parameters.Length; i++) { arguments[i] = Expression.Field(requestArg, "Item" + (i + 1)); } } var callBody = Expression.Call(getInstanceCast, methodInfo, arguments); var finalMethod = (methodInfo.ReturnType.IsGenericType) ? typeof(StreamingHubContext).GetMethod(nameof(StreamingHubContext.WriteResponseMessage), flags).MakeGenericMethod(UnwrappedResponseType) : typeof(StreamingHubContext).GetMethod(nameof(StreamingHubContext.WriteResponseMessageNil), flags); callBody = Expression.Call(contextArg, finalMethod, callBody); var body = Expression.Block(new[] { requestArg }, assignRequest, callBody); var compiledBody = Expression.Lambda(body, contextArg).Compile(); this.MethodBody = BuildMethodBodyWithFilter((Func <StreamingHubContext, ValueTask>)compiledBody); } catch (Exception ex) { throw new InvalidOperationException($"Can't create handler. Path:{ToString()}", ex); } }
/// <summary> /// Main /// </summary> /// <param name="args">参数</param> public static void Main(string[] args) { Environment.SetEnvironmentVariable("SETTINGS_MAX_HEADER_LIST_SIZE", "1000000"); GrpcEnvironment.SetLogger(new ConsoleLogger()); var options = new MagicOnionOptions(true) { MagicOnionLogger = new MagicOnionLogToGrpcLoggerWithNamedDataDump(), GlobalFilters = new MagicOnionFilterAttribute[] { }, EnableCurrentContext = true }; var service = MagicOnionEngine.BuildServerServiceDefinition(new Assembly[] { typeof(MyCalculateService).Assembly }, options); var server = new Grpc.Core.Server() { Services = { service }, Ports = { new ServerPort("192.168.2.22", 5001, ServerCredentials.Insecure) }, }; server.Start(); CreateWebHostBuilder(service, args).Build().Run(); }