当前位置: 移动技术网 > IT编程>开发语言>.net > ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

ASP.NET Core 3.0 上的gRPC服务模板初体验(多图)

2019年04月02日  | 移动技术网IT编程  | 我要评论

婴儿翻白眼,davidbelle,邯郸市中考分数线

早就听说asp.net core 3.0中引入了grpc的服务模板,正好趁着家里电脑刚做了新系统,然后装了vs2019的功夫来体验一把。同时记录体验的过程。如果你也想按照本文的步骤体验的话,那你得先安装.net core3.0预览版的sdk。至于开发工具我用的时vs2019,当然你也可以使用vs code进行。

作者:依乐祝
原文地址:https://www.cnblogs.com/yilezhu/p/10631420.html

grpc的简单介绍

grpc 是一种与语言无关的高性能远程过程调用 (rpc) 框架。 有关 grpc 基础知识的详细信息,请参阅 grpc 文档页

grpc 的主要优点是:

  • 现代高性能轻量级 rpc 框架。
  • 协定优先 api 开发,默认使用协议缓冲区,允许与语言无关的实现。
  • 可用于多种语言的工具,以生成强类型服务器和客户端。
  • 支持客户端、服务器和双向流式处理调用。
  • 使用 protobuf 二进制序列化减少对网络的使用。

这些优点使 grpc 适用于:

  • 效率至关重要的轻量级微服务。
  • 需要多种语言用于开发的 polyglot 系统。
  • 需要处理流式处理请求或响应的点对点实时服务。

asp.net core 3.0上grpc服务模板初体验

创建grpc服务

  1. 打开vs2019 从 visual studio“文件”菜单中选择“新建” > “项目”。(由于我是新打开的vs,所以按照如下图所示创建新项目)

    1554009071721

  2. 如下图所示,选择创建《asp.net core web 应用程序》,然后点击下一步

    1554009107868

  3. 在此页面按照下图所示,输入项目名称,位置,解决方案名称,然后点击右下角的“创建”按钮进行创建。

    1554009210208

  4. 你以为上述步骤中点击“创建”就结束了嘛?说好的要创建grpc服务模板的,所以,点击上面的创建后会弹出如下图所示,让你选择服务模板的窗口,这里按照下图所示选择grpc服务模板,然后再次点击右下角的创建,才是真正的创建项目。

    1554009368040

  5. 创建成功后,会出现如下图所示的项目结构

    1554009441048

  6. 至此,我们就创建好了一个grpc服务的模板,接下来我们先测试一番,然后再好好的看下这个模板的结构吧

测试grpc服务

  1. 首先打开hellogrpc.server 这个服务端的工作目录,然后shift+鼠标右键弹出如下图所示的右键菜单,如图所示打开ps窗口

    1554009655486

  2. 输入dotnet run 命令运行此grpc服务端项目,如下图所示,说明服务端启动正常,并开始监听对应的端口。

    1554009713142

  3. 同样的方法,我们启动客户端,这时候客户端会向该服务端发送一条包含具有其名称“greeterclient”的消息的问候信息。 该服务端将发送一条消息“hello greeterclient”作为响应,并显示在命令提示符中。如下图所示:

    1554009820515

  4. 至此,grpc服务模板创建的服务端以及客户端测试成功。下面我们就好好的探究一下这个服务模板吧。

grpc模板解析

hellogrpc.server 服务的端项目中有如下几个文件

  • greet.proto:greet.proto 文件定义 greeter grpc,且用于生成 grpc 服务器资产。
  • services 文件夹:包含 greeter 服务的实现。
  • appsettings.json:包含配置数据,如 kestrel 使用的协议。(熟悉asp.net core的你一定很熟悉)
  • program.cs:包含 grpc 服务的入口点。(熟悉asp.net core的你一定很熟悉)
  • startup.cs:iwebhostbuilder的启动配置文件,包含配置应用行为的代码。(熟悉asp.net core的你一定很熟悉)

grpc 客户端 hellogrpc.client 文件:

program.cs 包含 grpc 客户端的入口点和逻辑。

下面我们再打开每个文件看看里面究竟是什么东东吧。

proto文件

proto

grpc使用约定优先的api开发方法。默认情况下,使用协议缓冲区(protobuf)作为接口设计语言(idl)。这个.proto文件包含:

  • grpc服务的定义。
  • 在客户端和服务器之间发送的消息。

有关protobuf文件语法的更多信息,请参见.

如我们模板中创建的greet.proto 文件内容如下:

syntax = "proto3";

package greet;

// the greeting service definition.
service greeter {
  // sends a greeting
  rpc sayhello (hellorequest) returns (helloreply) {}
}

// the request message containing the user's name.
message hellorequest {
  string name = 1;
}

// the response message containing the greetings.
message helloreply {
  string message = 1;
}
  • 定义greeter服务。
  • 这个greeter服务定义sayhello请求。
  • sayhello发送hellorequest消息并接收helloresponse信息:
    那么你可能要问了,这个.proto文件是如何包含在项目中的呢,其实,如果你打开.csproject文件就会看到,通过将该文件添加到<protobuf>的itemgroup中即可,如下所示:
<itemgroup>
  <protobuf include="..\protos\*.proto" grpcservices="server" />
  <content include="@(protobuf)" linkbase="" />
</itemgroup>

c#对.proto文件的工具支持

工具包grpc.tools 被用来从.proto文件生成c#文件。生成的资产(文件)具有如下特性:

  • 每次构建项目时都会根据需要进行生成。
  • 生成的文件不会被添加到项目或签入源代码管理。
  • 生成的c#文件是包含在obj目录。

服务器和客户端项目都需要此包。grpc.tools可以通过在visualstudio中使用包管理器或添加<packagereference>到项目文件:

xml复制

<packagereference include="grpc.tools" version="1.19.0-pre1" privateassets="all" />

工具包在运行时并不是必需的,因此,应该用privateassets="all".

services 文件夹中的具体的grpc服务

我们知道grpc.tools工具包将根据.proto文件的定义翻译并生成对应的c#类型的文件。

对于服务器端资产,将生成一个抽象的服务基类型。基类型包含在.proto文件中包含的所有grpc调用的定义。然后,您将创建从此基类型派生的具体服务实现,并实现grpc调用的逻辑。对于前面描述的greet.proto示例,将生成包含虚拟sayhello方法的抽象greeterbase类型。具体的实现greeterservice重写该方法并实现处理grpc调用的逻辑。
正如hellogrpc.server项目中的services\greeterservice.cs中的代码

public class greeterservice : greeter.greeterbase
{
    public override task<helloreply> 
        sayhello(hellorequest request, servercallcontext context)
    {
        return task.fromresult(new helloreply
        {
            message = "hello " + request.name
        });
    }
}

对于客户端,将生成一个具体的客户端类型中的grpc调用。.proto文件被转换为可以调用的具体类型上的方法。为greet.proto前面描述的示例,一个具体的greeterclient类型生成。这个greeterclient类型包含sayhello方法,可以调用该方法来启动对服务器的grpc调用。

public class program
{
    static async task main(string[] args)
    {
        // include port of the grpc server as an application argument
        var port = args.length > 0 ? args[0] : "50051";

        var channel = new channel("localhost:" + port, channelcredentials.insecure);
        var client = new greeter.greeterclient(channel);

        var reply = await client.sayhelloasync(
                                      new hellorequest { name = "greeterclient" });
        console.writeline("greeting: " + reply.message);

        await channel.shutdownasync();

        console.writeline("press any key to exit...");
        console.readkey();
    }
}

默认情况下,分别生成服务器和客户端资产。.proto文件包含在<protobuf>项目组。若要确保仅在服务器项目中生成服务器资产,grpcservices属性设置为server.

xml复制

<itemgroup>
  <protobuf include="..\protos\*.proto" grpcservices="server" />
  <content include="@(protobuf)" linkbase="" />
</itemgroup>

类似地,属性设置为client在仅在客户项目中生成。

startup

startup中我们发现跟普通的asp.net core程序有所不同,具体的如下图所示:在configureservices 服务中引入了grpc服务,然后在configure加入了路由

1554014291599

而这里需要引入三个与grpc相关的nuget包

这里需要说明的是

asp.net core 中间件和功能共享路由管道,因此可以将应用程序配置为服务其他请求处理程序。其他请求处理程序(如mvc控制器)可以与配置的grpc服务路由并行工作。

其他需要说明的内容

与asp.net core 接口的集成

grpc服务可以完全访问asp.netcore功能,如依赖注入(di)和日志功能。例如,服务实现可以通过构造函数解析di容器中的记录器服务:

public class greeterservice : greeter.greeterbase
{
    public greeterservice(ilogger<greeterservice> logger)
    {
    }
}

默认情况下,grpc服务可以解析具有任意生存期的其他di服务(singleton, scoped, or transient)。

在grpc方法中解析httpcontext

grpc 应用程序接口提供对某些http/2消息数据的访问,例如method, host, header, and trailers。访问是通过servercallcontext参数传递给每个grpc方法:

public class greeterservice : greeter.greeterbase
{
    public override task<helloreply> 
        sayhello(hellorequest request, servercallcontext context)
    {
        return task.fromresult(new helloreply
        {
            message = "hello " + request.name
        });
    }
}

servercallcontext不提供对所有asp.net 接口中httpcontext的完全访问。gethttpcontext扩展方法提供对表示asp.net api中底层http/2消息的httpcontext的完全访问:

public class greeterservice : greeter.greeterbase
{
    public override task<helloreply> sayhello(hellorequest request, 
        servercallcontext context)
    {
        var httpcontext = context.gethttpcontext();

        return task.fromresult(new helloreply
        {
            message = "using https: " + httpcontext.request.ishttps
        });
    }
}

请求体数据速率限制

默认情况下,kestrel服务器设置为最小请求主体数据速率。对于客户端流式和双工流式的请求,此速率可能不满足,并且连接可能超时。当grpc服务包括客户端流和双工流调用时,必须禁用最小请求正文数据速率限制:

public class program
{
    public static void main(string[] args)
    {
        createhostbuilder(args).build().run();
    }

    public static ihostbuilder createhostbuilder(string[] args) =>
         host.createdefaultbuilder(args)
    .configurewebhostdefaults(webbuilder =>
    {
        webbuilder.usestartup<startup>();
        webbuilder.configurekestrel((context, options) =>
        {
            options.limits.minrequestbodydatarate = null;
        });
    });
}

参考文章

总结

今天分享的内容有点多,目的就是使记录尽可能的详细,尽可能用通俗易懂的语言来进行描述,让大家能用起来。在asp.net core3.0中把grpc服务作为第一等公民进行支持,所以我们有必要进行下了解。可能很多朋友会有疑问了,我web api用的爽歪歪,干嘛还要用grpc这种远程过程调用协议啊。关于这个问题,我准备再单独开一篇文章进行讲解,最后感谢大家的阅读,码字不易,多多推荐支持吧!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网