.NET8中gRPC的使用
在現代分布式系統中,服務之間的通信是一個非常重要的環節。隨著微服務架構的流行,服務之間的通信方式也在不斷演進。gRPC作為一種高性能、跨語言的RPC框架,逐漸成為了我們的首選。
一、簡介
gRPC 是一種高性能、開源的遠程過程調用(RPC)框架,基于 HTTP/2 協議,支持雙向流、頭部壓縮等特性。它默認使用 Protocol Buffers(Protobuf)作為接口定義語言(IDL)和數據序列化格式,適用于微服務、實時通信等場景。
在 .NET Core(.NET 8)中,gRPC 提供了原生的支持,我們可以輕松創建 gRPC 服務端和客戶端,并將其集成到 Web API 或其他應用中。
本文將圍繞以下幾個方面介紹如何在 .NET Core (.NET 8) 中使用 gRPC:
- 創建 gRPC 服務端
- 創建 gRPC 客戶端
- 在 Web API 中集成 gRPC
二、創建 gRPC 服務端
1. 創建 gRPC 項目
首先,使用 .NET CLI 創建一個 gRPC 服務端項目。也可以通過VS2022直接進行創建。
dotnet new grpc -o GrpcDemo.Service
cd GrpcDemo.Service

這將創建一個包含 gRPC 模板的項目,其中包含一個示例的 gRPC 服務。

2. 編寫自己的服務
在 Protos 文件夾中,默認會生成一個 greet.proto 文件。我們可以修改或創建新的 .proto 文件來定義自己的服務。
例如,創建一個 order.proto 文件:
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;
}
接下來,在 Services 文件夾中實現服務邏輯。創建一個 OrderService.cs 文件:
using Grpc.Core;
namespace GrpcDemo.Service.Services
{
public class OrderService : Order.OrderBase
{
private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger)
{
_logger = logger;
}
/// <summary>
/// 創建訂單
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<CreateResult> CreateOrder(CreateRequest request, ServerCallContext context)
{
//報存數據庫 todo
return Task.FromResult(new CreateResult
{
IsSuccess = true,
Message = "訂單創建成功"
});
}
/// <summary>
/// 查詢訂單
/// </summary>
/// <param name="request"></param>
/// <param name="context"></param>
/// <returns></returns>
public override Task<QueryResult> QueryOrder(QueryRequest request, ServerCallContext context)
{
//查詢數據庫 //todo
return Task.FromResult(new QueryResult
{
Id = request.Id,
OrderNo = DateTime.Now.ToString("yyyyMMddHHmmss"),
OrderName = "年貨大禮包",
Price = 699
});
}
}
}
在 Program.cs 中注冊服務:
using GrpcDemo.Service.Services;
var builder = WebApplication.CreateBuilder(args);
// 添加 gRPC 服務
builder.Services.AddGrpc();
var app = builder.Build();
// 映射 gRPC 服務
app.MapGrpcService<OrderService>();
app.Run();
運行項目后,gRPC 服務端將啟動并監聽指定的端口。
三、創建 gRPC 客戶端
1. 創建客戶端項目
使用 .NET CLI 創建一個控制臺項目作為 gRPC 客戶端:
dotnet new console -o GrpcDemo.Client
cd GrpcDemo.Client
2. 添加 gRPC 客戶端依賴
在客戶端項目中,添加 Grpc.Net.Client 和 Google.Protobuf 包:
dotnet add package Grpc.Net.Client
dotnet add package Google.Protobuf
dotnet add package Grpc.Tools
將服務端的 order.proto 文件復制到客戶端項目的 Protos 文件夾中,并在 .csproj 文件中添加以下內容以生成 C# 代碼:

3. 編寫客戶端代碼
在 Program.cs 中編寫 gRPC服務HTTPS調用的代碼:
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();
}
結果:

如果 gRPC 服務端使用 HTTP(非 HTTPS),可以在客戶端中直接使用 HTTP 地址:
//使用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();
結果:

四、Web API 中加入 gRPC
在 Web API 項目中,可以同時提供 RESTful API 和 gRPC 服務。以下是如何在 Web API 中集成 gRPC 的步驟:
1. 添加 gRPC 服務
在 Program.cs 中注冊 gRPC 服務:
var builder = WebApplication.CreateBuilder(args);
// 添加 gRPC 服務
builder.Services.AddGrpc();
var app = builder.Build();
// 映射 gRPC 服務
app.MapGrpcService<OrderService>();
app.Run();
2. 提供 RESTful API
在 Web API 中,可以通過控制器提供 RESTful API,并在內部調用 gRPC 服務:
using Microsoft.AspNetCore.Mvc;
namespace GrpcDemo.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class OrderController : ControllerBase
{
private readonly Order.OrderClient _client;
public OrderController(Order.OrderClient client)
{
_client = client;
}
[HttpGet("create")]
public async Task<IActionResult> CreateOrder()
{
var response = await _client.CreateOrderAsync(
new CreateRequest {
OrderNo = DateTime.Now.ToString("yyyyMMddHHmmssfff"),
OrderName = "年貨大禮包",
Price = 699
});
return Ok(response);
}
}
}
3. 配置 gRPC 客戶端
在 Program.cs 中注冊 gRPC 客戶端:
builder.Services.AddGrpcClient<Order.OrderClient>(options =>
{
options.Address = new Uri("http://localhost:5147");
});
結果:

總結
在 .NET Core 中,gRPC 提供了高性能的通信方式,適用于微服務、實時通信等場景。我們可以輕松創建 gRPC 服務端和客戶端,并將其集成到 Web API 中。
關鍵點:
- 使用
.proto文件定義服務接口。 - 實現 gRPC 服務端邏輯。
- 在客戶端中調用 gRPC 服務。
- 在 Web API 中集成 gRPC,提供 RESTful API 和 gRPC 服務。
通過以上步驟,我們就可以在 .NET Core 項目中充分利用 gRPC 的優勢,構建高效的分布式系統。


浙公網安備 33010602011771號