保持Dotnet Core Grpc Server作为控制台应用程序运行? [英] Keep Dotnet Core Grpc Server running as a console application?

查看:272
本文介绍了保持Dotnet Core Grpc Server作为控制台应用程序运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使Grpc服务器作为控制台守护程序运行。这个gRPC服务器是在docker容器中运行的微服务。

I am trying to keep a Grpc server running as a console daemon. This gRPC server is a microservice that runs in a docker container.

我可以找到的所有示例都利用以下内容:

All of the examples I can find make use of the following:

Console.ReadKey();

这确实会阻塞主线程并使其保持运行,但在Docker中不起作用,并出现以下错误:

This does indeed block the main thread and keeps it running but does not work in docker with the following error:

"Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read."

现在我可能可以尝试专门为docker找到一种解决方法,但这仍然感觉不对。有人知道保持服务运行的良好生产就绪方法吗?

Now I could probably try to find a workaround for docker specifically, but this still doesn't feel right. Does anyone know of a good "production ready" way to keep the service running?

推荐答案

您现在可以使用 Microsoft.Extensions.Hosting pacakge,它是asp.net核心和控制台应用程序的托管和启动基础结构。

You can now use Microsoft.Extensions.Hosting pacakge which is a hosting and startup infrastructures for both asp.net core and console application.

像asp。 NET Core,您可以使用HostBuilder API开始构建gRPC主机并进行设置。以下代码是要获取一个一直运行直到停止的控制台应用程序(例如,使用Control-C):

Like asp.net core, you can use the HostBuilder API to start building gRPC host and setting it up. The following code is to get a console application that keeps running until it is stopped (for example using Control-C):

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder();

         // register your configuration and services.
        ....

        await hostBuilder.RunConsoleAsync();
    }
}

要运行gRPC服务,您需要在托管服务中启动/停止 Grpc.Core.Server 。托管服务基本上是一段代码,它在主机本身启动时由主机运行,而在主机停止时相同。这在IHostedService接口中表示。也就是说,实现GrpcHostedService来覆盖该接口:

In order to run the gRPC service, you need to start/stop Grpc.Core.Server in a hosted service. A hosted service is basically a piece of code that is run by the host when the host itself is started and the same for when it is stopped. This is represented in the IHostedService interface. That's to say, implement a GrpcHostedService to override the interface:

using System.Threading;
using System.Threading.Tasks;
using Grpc.Core;
using Microsoft.Extensions.Hosting;

namespace Grpc.Host
{
    public class GrpcHostedService: IHostedService
    {
        private Server _server;

        public GrpcHostedService(Server server)
        {
            _server = server;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _server.Start();
            return Task.CompletedTask;
        }

        public async Task StopAsync(CancellationToken cancellationToken) => await _server.ShutdownAsync();
    }
}

这真的很简单。我们通过依赖项注入获得了一个 GrpcHostedService 实例,并在主机启动时对其运行StartAsync。当主机停止时,我们运行StopAsync,以便我们可以正常关闭所有内容,包括Grpc服务器。

It's simple really. We get an GrpcHostedService instance injected through dependency injection and run StartAsync on it when host is started. When the host is stopped we run StopAsync so that we can gracefully shut everything down including Grpc server.

然后返回 Program.cs 并进行一些更改:

Then go back to the Program.cs and make some changes:

public class Program
{
    public static async Task Main(string[] args)
    {
        var hostBuilder = new HostBuilder()
             // Add configuration, logging, ...
            .ConfigureServices((hostContext, services) =>
            {
                // Better to use Dependency Injection for GreeterImpl
                Server server = new Server
                {
                    Services = {Greeter.BindService(new GreeterImpl())},
                    Ports = {new ServerPort("localhost", 5000, ServerCredentials.Insecure)}
                };
                services.AddSingleton<Server>(server);
                services.AddSingleton<IHostedService, GrpcHostedService>();
            });

        await hostBuilder.RunConsoleAsync();
    }
}

这样做,通用主机将自动运行StartAsync在我们的托管服务上,该服务随后会在 Server 实例上调用StartAsync,实际上是启动gRPC服务器。

By doing this, the generic host will automatically run StartAsync on our hosted service, which in turn will call StartAsync on the Server instance, essentially start the gRPC server.

当我们使用Control-C关闭主机时,通用主机将自动在托管服务上调用StopAsync,这又将在 Server 实例上调用StopAsync

When we shut down the host with Control-C, the generic host will automatically call StopAsync on our hosted service, which again will call StopAsync on the Server instance which will do some clean up.

对于HostBuilder中的其他配置,您可以看到此博客

For other configuration in HostBuilder, you can see this blog.

这篇关于保持Dotnet Core Grpc Server作为控制台应用程序运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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