白珊 發表於 2025-3-19 09:49:00

.NET8中gRPC的使用

<blockquote>
<p>在现代分布式系统中,服务之间的通信是一个非常重要的环节。随着微服务架构的流行,服务之间的通信方式也在不断演进。gRPC作为一种高性能、跨语言的RPC框架,逐渐成为了我们的首选。</p>
</blockquote>
<h2 id="一简介">一、简介</h2>
<p>gRPC 是一种高性能、开源的远程过程调用(RPC)框架,基于 HTTP/2 协议,支持双向流、头部压缩等特性。它默认使用 Protocol Buffers(Protobuf)作为接口定义语言(IDL)和数据序列化格式,适用于微服务、实时通信等场景。</p>
<p>在 .NET Core(.NET 8)中,gRPC 提供了原生的支持,我们可以轻松创建 gRPC 服务端和客户端,并将其集成到 Web API 或其他应用中。</p>
<p>本文将围绕以下几个方面介绍如何在 .NET Core (.NET 8) 中使用 gRPC:</p>
<ol>
<li>创建 gRPC 服务端</li>
<li>创建 gRPC 客户端</li>
<li>在 Web API 中集成 gRPC</li>
</ol>
<h2 id="二创建-grpc-服务端">二、创建 gRPC 服务端</h2>
<h3 id="1-创建-grpc-项目">1. 创建 gRPC 项目</h3>
<p>首先,使用 .NET CLI 创建一个 gRPC 服务端项目。<font style="color: rgba(64, 64, 64, 1)">也可以通过VS2022直接进行创建。</font></p>
<pre><code class="language-bash">dotnet new grpc -o GrpcDemo.Service
cd GrpcDemo.Service
</code></pre>
<p><img src="https://fastly.jsdelivr.net/gh/bucketio/img3@main/2025/01/25/1737795543433-38c57f50-626b-4fe2-9890-6431ef5ffa08.png"></p>
<p>这将创建一个包含 gRPC 模板的项目,其中包含一个示例的 gRPC 服务。</p>
<p><img src="https://fastly.jsdelivr.net/gh/bucketio/img14@main/2025/01/25/1737795586791-5bda56fb-ee3c-453e-a503-2121a7d4542d.png"></p>
<h3 id="2-编写自己的服务">2. 编写自己的服务</h3>
<p>在 <code>Protos</code> 文件夹中,默认会生成一个 <code>greet.proto</code> 文件。我们可以修改或创建新的 <code>.proto</code> 文件来定义自己的服务。</p>
<p>例如,创建一个 <code>order.proto</code> 文件:</p>
<pre><code class="language-protobuf">syntax = "proto3";

option csharp_namespace = "GrpcDemo.Service";

package order;

// 订单服务定义
service Order {
// 创建订单
rpc CreateOrder (CreateRequest) returns (CreateResult);
//查询订单
rpc QueryOrder (QueryRequest) returns (QueryResult);
}

//创建订单请求参数
message CreateRequest {
string OrderNo = 1;
string OrderName=2;
double Price=3;
}

//创建订单返回结果
message CreateResult {
bool IsSuccess = 1; // 是否成功
string Message = 2; // 错误信息
}

//查询订单请求参数
message QueryRequest{
int32 Id=1;
}
//查询订单返回结果
message QueryResult{
int32 Id=1;
string OrderNo=2;
string OrderName=3;
double Price=4;
}
</code></pre>
<p>接下来,在 <code>Services</code> 文件夹中实现服务逻辑。创建一个 <code>OrderService.cs</code> 文件:</p>
<pre><code class="language-csharp">using Grpc.Core;

namespace GrpcDemo.Service.Services
{
    public class OrderService : Order.OrderBase
    {
      private readonly ILogger&lt;OrderService&gt; _logger;
      public OrderService(ILogger&lt;OrderService&gt; logger)
      {
            _logger = logger;
      }
      /// &lt;summary&gt;
      /// 创建订单
      /// &lt;/summary&gt;
      /// &lt;param name="request"&gt;&lt;/param&gt;
      /// &lt;param name="context"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public override Task&lt;CreateResult&gt; CreateOrder(CreateRequest request, ServerCallContext context)
      {
            //报存数据库 todo

            return Task.FromResult(new CreateResult
            {
                IsSuccess = true,
                Message = "订单创建成功"
            });
      }
      /// &lt;summary&gt;
      /// 查询订单
      /// &lt;/summary&gt;
      /// &lt;param name="request"&gt;&lt;/param&gt;
      /// &lt;param name="context"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      public override Task&lt;QueryResult&gt; QueryOrder(QueryRequest request, ServerCallContext context)
      {
            //查询数据库 //todo

            return Task.FromResult(new QueryResult
            {
                  Id = request.Id,
                  OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),
                  OrderName = "年货大礼包",
                  Price = 699
            });
      }
    }
}

</code></pre>
<p>在 <code>Program.cs</code> 中注册服务:</p>
<pre><code class="language-csharp">using GrpcDemo.Service.Services;

var builder = WebApplication.CreateBuilder(args);

// 添加 gRPC 服务
builder.Services.AddGrpc();

var app = builder.Build();

// 映射 gRPC 服务
app.MapGrpcService&lt;OrderService&gt;();

app.Run();
</code></pre>
<p>运行项目后,gRPC 服务端将启动并监听指定的端口。</p>
<h2 id="三创建-grpc-客户端">三、创建 gRPC 客户端</h2>
<h3 id="1-创建客户端项目">1. 创建客户端项目</h3>
<p>使用 .NET CLI 创建一个控制台项目作为 gRPC 客户端:</p>
<pre><code class="language-bash">dotnet new console -o GrpcDemo.Client
cd GrpcDemo.Client
</code></pre>
<h3 id="2-添加-grpc-客户端依赖">2. 添加 gRPC 客户端依赖</h3>
<p>在客户端项目中,添加 <code>Grpc.Net.Client</code> 和 <code>Google.Protobuf</code> 包:</p>
<pre><code class="language-csharp">dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
</code></pre>
<p>将服务端的 <code>order.proto</code> 文件复制到客户端项目的 <code>Protos</code> 文件夹中,并在 <code>.csproj</code> 文件中添加以下内容以生成 C# 代码:<br>
<img src="https://fastly.jsdelivr.net/gh/bucketio/img1@main/2025/01/25/1737795484246-8c31c246-9159-4b32-9200-0681eaf2f89b.png"></p>
<h3 id="3-编写客户端代码">3. 编写客户端代码</h3>
<p>在 <code>Program.cs</code> 中编写 gRPC服务HTTPS调用的代码:</p>
<pre><code class="language-csharp">static void Main(string[] args)
{
    Console.WriteLine("Hello, World!");
    //常规使用,https
    string url = "https://localhost:7231";
    using (var channel = GrpcChannel.ForAddress(url))
    {
      var client = new Order.OrderClient(channel);
      var reply = client.CreateOrder(new CreateRequest()
      {
            OrderNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
            OrderName = "年货大礼包",
            Price = 699
      });

      Console.WriteLine($"Grpc服务https的调用结果:{reply.IsSuccess},message:{reply.Message}");
    }
    Console.ReadKey();

}
</code></pre>
<p>结果:<br>
<img src="https://fastly.jsdelivr.net/gh/bucketio/img8@main/2025/01/25/1737795409412-de4df56d-e5fe-406f-8d77-8cc2d90548fc.jpg"></p>
<p>如果 gRPC 服务端使用 HTTP(非 HTTPS),可以在客户端中直接使用 HTTP 地址:</p>
<pre><code class="language-csharp"> //使用http
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
string url = "http://localhost:5147";

using (var channel = GrpcChannel.ForAddress(url))
{
   var client = new Order.OrderClient(channel);
   var reply = client.CreateOrder(new CreateRequest()
   {
         OrderNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
         OrderName = "年货大礼包",
         Price = 699
   });

   Console.WriteLine($"gGrpc内网http调用结果:{reply.IsSuccess},message:{reply.Message}");
}
Console.ReadKey();
</code></pre>
<p>结果:<br>
<img src="https://fastly.jsdelivr.net/gh/bucketio/img17@main/2025/01/25/1737795381222-19b769b5-f4d3-4cab-8a03-9977341584a0.jpg"></p>
<h2 id="四web-api-中加入-grpc">四、Web API 中加入 gRPC</h2>
<p>在 Web API 项目中,可以同时提供 RESTful API 和 gRPC 服务。以下是如何在 Web API 中集成 gRPC 的步骤:</p>
<h3 id="1-添加-grpc-服务">1. 添加 gRPC 服务</h3>
<p>在 <code>Program.cs</code> 中注册 gRPC 服务:</p>
<pre><code class="language-csharp">var builder = WebApplication.CreateBuilder(args);

// 添加 gRPC 服务
builder.Services.AddGrpc();

var app = builder.Build();

// 映射 gRPC 服务
app.MapGrpcService&lt;OrderService&gt;();

app.Run();
</code></pre>
<h3 id="2-提供-restful-api">2. 提供 RESTful API</h3>
<p>在 Web API 中,可以通过控制器提供 RESTful API,并在内部调用 gRPC 服务:</p>
<pre><code class="language-csharp">using Microsoft.AspNetCore.Mvc;

namespace GrpcDemo.API.Controllers
{
   
    ")]
    public class OrderController : ControllerBase
    {
      private readonly Order.OrderClient _client;

      public OrderController(Order.OrderClient client)
      {
            _client = client;
      }

      
      public async Task&lt;IActionResult&gt; CreateOrder()
      {
            var response = await _client.CreateOrderAsync(
                new CreateRequest {
                  OrderNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
                  OrderName = "年货大礼包",
                  Price = 699
                });
            return Ok(response);
      }

    }
}

</code></pre>
<h3 id="3-配置-grpc-客户端">3. 配置 gRPC 客户端</h3>
<p>在 <code>Program.cs</code> 中注册 gRPC 客户端:</p>
<pre><code class="language-csharp"> builder.Services.AddGrpcClient&lt;Order.OrderClient&gt;(options =&gt;
{
   options.Address = new Uri("http://localhost:5147");
});

</code></pre>
<p>结果:<br>
<img src="https://fastly.jsdelivr.net/gh/bucketio/img19@main/2025/01/25/1737795335855-1ee4db8c-3adc-421d-a967-3f9b6393f244.jpg"></p>
<h2 id="总结">总结</h2>
<p>在 .NET Core 中,gRPC 提供了高性能的通信方式,适用于微服务、实时通信等场景。我们可以轻松创建 gRPC 服务端和客户端,并将其集成到 Web API 中。</p>
<p>关键点:</p>
<ol>
<li>使用 <code>.proto</code> 文件定义服务接口。</li>
<li>实现 gRPC 服务端逻辑。</li>
<li>在客户端中调用 gRPC 服务。</li>
<li>在 Web API 中集成 gRPC,提供 RESTful API 和 gRPC 服务。</li>
</ol>
<p>通过以上步骤,我们就可以在 .NET Core 项目中充分利用 gRPC 的优势,构建高效的分布式系统。</p>
<blockquote>
<p>源码地址:https://github.com/liyongqiang-cc/GrpcDemo<br>
<img src="https://img2024.cnblogs.com/blog/2063798/202503/2063798-20250319094748394-306274407.png"></p>
</blockquote><br><br>
来源:https://www.cnblogs.com/liyongqiang-cc/p/18691064
頁: [1]
查看完整版本: .NET8中gRPC的使用