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

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

问题描述

我试图让 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 服务器作为控制台应用程序运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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