コード例 #1
0
 /// <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
             }
                 );
         });
     }));
 }
コード例 #2
0
        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);
        }
コード例 #3
0
        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();
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
0
 /// <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));
 }
コード例 #6
0
        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();
            }
        }
コード例 #7
0
 public override void OnApplicationInitialization(ApplicationInitializationContext context)
 {
     using (var scope = context.ServiceProvider.CreateScope())
     {
         var magicOnionOption = new MagicOnionOptions();
         magicOnionOption.IsReturnExceptionStackTraceInErrorDetail = false;
     }
 }
コード例 #8
0
 public StreamingHubHandlerOptions(MagicOnionOptions options)
 {
     GlobalStreamingHubFilters = options.GlobalStreamingHubFilters;
     Logger            = options.MagicOnionLogger;
     FormatterResolver = options.FormatterResolver;
     ServiceLocator    = options.ServiceLocator;
     ServiceActivator  = options.MagicOnionServiceActivator;
 }
コード例 #9
0
 public StreamingHubHandlerOptions(MagicOnionOptions options)
 {
     GlobalStreamingHubFilters = options.GlobalStreamingHubFilters;
     Logger            = options.MagicOnionLogger;
     SerializerOptions = options.SerializerOptions;
     ServiceLocator    = options.ServiceLocator;
     ServiceActivator  = options.MagicOnionServiceActivator;
 }
コード例 #10
0
        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);
        }
コード例 #11
0
        /// <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);
                });
            }));
        }
コード例 #12
0
ファイル: _ServerFixture.cs プロジェクト: lin5/MagicOnion
        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);
        }
コード例 #13
0
 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));
 }
コード例 #14
0
        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);
        }
コード例 #15
0
        /// <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;
                });
            }));
        }
コード例 #16
0
        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. ---------------------------------");
        }
コード例 #17
0
 public ServiceLocatorTest(ServiceLocatorTestServerFixture serverFixture)
 {
     channel = serverFixture.DefaultChannel;
     options = serverFixture.Options;
 }
コード例 #18
0
ファイル: _ServerFixture.cs プロジェクト: lin5/MagicOnion
 protected virtual MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options)
 => MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ServerFixture).GetTypeInfo().Assembly }, options);
コード例 #19
0
 /// <summary>
 /// Search MagicOnion service from all assemblies.
 /// </summary>
 public static MyServerServiceDefinition Build(MagicOnionOptions options)
 {
     return(BuildServerServiceDefinition(AppDomain.CurrentDomain.GetAssemblies(), options));
 }
コード例 #20
0
        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();
            //}
        }
コード例 #21
0
ファイル: Program.cs プロジェクト: gpg1993/TestNotes
        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());
        }
コード例 #22
0
 protected override void ConfigureMagicOnion(MagicOnionOptions options)
 {
 }
コード例 #23
0
 //private static AsyncLocal<IServiceProvider> dics = new AsyncLocal<IServiceProvider>();
 //public static IServiceProvider current => dics.Value;
 public ServiceLocatorBridge(IServiceScopeFactory serviceProvider, MagicOnionOptions magicOnionOptions)
 {
     _serviceProvider = serviceProvider;
 }
コード例 #24
0
 protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options)
 {
     return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(FilterConstructorInjectionTester) }, options));
 }
コード例 #25
0
ファイル: ClientConfigTest.cs プロジェクト: ywscr/MagicOnion
 protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options)
 {
     return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(ConfigurationChange) }, options));
 }
コード例 #26
0
 public StreamingHubHandlerOptions(MagicOnionOptions options)
 {
     GlobalStreamingHubFilters = options.GlobalStreamingHubFilters;
     SerializerOptions         = options.SerializerOptions;
 }
コード例 #27
0
 protected abstract MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options);
コード例 #28
0
 protected override MagicOnionServiceDefinition BuildServerServiceDefinition(MagicOnionOptions options)
 {
     options.DefaultGroupRepositoryFactory = new ImmutableArrayGroupRepositoryFactory();
     return(MagicOnionEngine.BuildServerServiceDefinition(new[] { typeof(StreamingHubBroadcastTestHub) }, options));
 }
コード例 #29
0
        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);
            }
        }
コード例 #30
-1
        /// <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();
        }