每次调用实例化的GRPC服务 [英] GRPC service instantiated per call

查看:83
本文介绍了每次调用实例化的GRPC服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在.NET core 3.1下创建了一个GRPC服务主机(使用https://github.com/grpc/grpc-dotnet中的Grpc.AspNetCore v2.30)。通过在";ProxyService";构造函数中放置断点,我可以看到该类在每次调用时都被实例化--每次来自客户端的GRPC调用都会命中断点。如何将其配置为始终使用相同的ProxyService实例?

以下是程序类和启动类:

    class Program
    {
        const int _port = 23456;

        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
            Console.WriteLine("started - press any key to quit...");
            Console.ReadKey();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(options =>
                    {
                        options.ConfigureEndpointDefaults(o =>
                        {
                            o.Protocols = HttpProtocols.Http2;
                            
                        });
                        options.ListenAnyIP(_port);
                    });
                    webBuilder.UseStartup<Startup>();
                });
    }

    public class ProxyService : StreamingApi.Protos.StreamingApi.StreamingApiBase
    {
        public ProxyService()
        {
    // gets here with every client call
        }

        public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
        {
            return Task.FromResult(new UpdateResponse());
        }
    }

   class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<ProxyService>();
            });
        }
    }

推荐答案

首先,让我猜猜您为什么要这样做:

  • 您在ProxyService中有一些繁重的逻辑,比如某种初始化;
  • 您有要在调用之间共享的静态变量;

要解决第一种情况,您应该使用任一方法本身:

    public ProxyService(IFooBar foobar)
    {
        this.foobar = foobar;
    }
    public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
    {
        await this.foobar.InitializeAsync();
        return Task.FromResult(new UpdateResponse());
    }

或系统中的某些其他触发器,例如服务启动时的触发器:

    public interface IFooBarInitilizer :IHostedService
    {
    }
    public class FooBarInitilizer : IFooBarInitilizer 
    {
        public async Task StartAsync(CancellationToken token){ await this.foobar.InitializeAsync(); }
    }

    //in your Configure
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
        services.AddSingleton<IFooBarInitializer, FooBarInitializer>();
        services.AddHostedService(x=> x.GetService<IFooBarInitializer>());
    }

对于第二种情况,它甚至更简单,因为您只需通过接口依赖指定您的共享资源:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
        services.AddSingleton<IFooBarResource, FooBarResource>();
    }

    
public class ProxyService : StreamingApi.Protos.StreamingApi.StreamingApiBase
{
    public ProxyService(IFooBarResource myStaticResource)
    {
        this.myStaticResource = myStaticResource;
    }

    public override Task<UpdateResponse> Update(UpdateRequest request, ServerCallContext context)
    {
        var somethingGood = this.myStaticResource.GetMeSomethingGood();
        return Task.FromResult(new UpdateResponse());
    }
}

这篇关于每次调用实例化的GRPC服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆