您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# .Net Core中使用Grpc的方法
## 一、Grpc技术概述
### 1.1 什么是Grpc
gRPC(Google Remote Procedure Call)是一个高性能、开源的通用RPC框架,由Google开发并基于HTTP/2协议标准设计。它采用Protocol Buffers(protobuf)作为默认的接口定义语言(IDL)和序列化工具,具有以下核心特点:
- **跨语言支持**:支持C++, Java, Python, Go, Ruby, C#, Node.js等多种语言
- **高效的二进制编码**:使用protobuf实现高效的序列化/反序列化
- **基于HTTP/2**:支持双向流、头部压缩、多路复用等特性
- **强类型服务定义**:通过.proto文件明确定义服务接口
### 1.2 Grpc与传统REST对比
| 特性 | gRPC | REST/JSON |
|---------------------|--------------------------|------------------------|
| 协议 | HTTP/2 | HTTP/1.1 |
| 数据格式 | Protobuf(二进制) | JSON(文本) |
| 性能 | 高(二进制+HTTP/2) | 中等 |
| 流式支持 | 双向流 | 有限支持 |
| 代码生成 | 自动生成客户端/服务端代码 | 手动编写 |
| 浏览器支持 | 有限(需要grpc-web) | 全面支持 |
## 二、.NET Core中的Grpc开发环境配置
### 2.1 必要工具安装
1. **.NET SDK**:确保安装.NET 6+(推荐.NET 8)
```bash
dotnet --version
Visual Studio扩展(可选):
Protocol Buffer编译器:
# Windows
choco install protoc
# macOS
brew install protobuf
修改.csproj
文件添加必要依赖:
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.54.0" />
<PackageReference Include="Google.Protobuf" Version="3.24.4" />
<PackageReference Include="Grpc.Tools" Version="2.54.0" PrivateAssets="All" />
</ItemGroup>
在Protos
文件夹下创建greeter.proto
:
syntax = "proto3";
option csharp_namespace = "GrpcDemo.Services";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
rpc ServerStreaming (Request) returns (stream Response);
rpc ClientStreaming (stream Request) returns (Response);
rpc BidirectionalStreaming (stream Request) returns (stream Response);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
message Request {
int32 value = 1;
}
message Response {
int32 value = 1;
}
项目文件中配置protobuf编译:
<ItemGroup>
<Protobuf Include="Protos\greeter.proto" GrpcServices="Server" />
</ItemGroup>
编译后会自动生成:
- GreeterBase
抽象类(服务端继承)
- Greeter.GreeterClient
类(客户端使用)
public class GreeterService : Greeter.GreeterBase
{
private readonly ILogger<GreeterService> _logger;
public GreeterService(ILogger<GreeterService> logger)
{
_logger = logger;
}
public override Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
public override async Task ServerStreaming(Request request,
IServerStreamWriter<Response> responseStream,
ServerCallContext context)
{
for (var i = 0; i < 5; i++)
{
await responseStream.WriteAsync(new Response { Value = i });
await Task.Delay(200);
}
}
}
在Program.cs
中配置:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
builder.Services.AddGrpcReflection(); // 可选:用于服务发现
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "gRPC服务运行中...");
app.Run();
builder.Services.AddGrpc(options => {
options.EnableDetailedErrors = true;
options.MaxReceiveMessageSize = 2 * 1024 * 1024; // 2MB
options.MaxSendMessageSize = 5 * 1024 * 1024; // 5MB
});
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
// 一元调用
var reply = await client.SayHelloAsync(
new HelloRequest { Name = "World" });
Console.WriteLine(reply.Message);
// 服务端流
var cts = new CancellationTokenSource();
var streamingCall = client.ServerStreaming(
new Request { Value = 10 });
await foreach (var response in streamingCall.ResponseStream
.ReadAllAsync(cts.Token))
{
Console.WriteLine($"Received: {response.Value}");
}
注册类型化客户端:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(options =>
{
options.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
return handler;
});
// 服务端配置
webBuilder.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
listenOptions.UseHttps("server.pfx", "password");
});
});
// 客户端配置
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpClient = new HttpClient(new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
})
});
// 服务端
builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "https://demo.identityserver.io";
options.Audience = "grpc-api";
});
app.UseAuthentication();
app.UseAuthorization();
// 在服务方法中使用
[Authorize]
public override Task<HelloReply> SayHello(...)
// 客户端
var headers = new Metadata();
headers.Add("Authorization", $"Bearer {token}");
var response = await client.SayHelloAsync(
new HelloRequest(),
headers: headers);
// 使用单例Channel
services.AddSingleton(GrpcChannel.ForAddress("https://localhost:5001"));
var channel = GrpcChannel.ForAddress("dns:///my-service", new GrpcChannelOptions
{
Credentials = ChannelCredentials.Insecure,
ServiceConfig = new ServiceConfig
{
LoadBalancingConfigs = { new RoundRobinConfig() }
}
});
// 服务端
services.AddGrpc(options =>
{
options.ResponseCompressionLevel = CompressionLevel.Optimal;
options.CompressionProviders = new List<ICompressionProvider>
{
new GzipCompressionProvider(CompressionLevel.Fastest)
};
});
// 客户端
var callOptions = new CallOptions(
compressionAlgorithm: "gzip");
try
{
var response = await client.SayHelloAsync(request);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.NotFound)
{
// 处理特定错误
}
grpcurl -plaintext localhost:5001 list
channel.State // Idle, Connecting, Ready, TransientFailure, Shutdown
service OrderService {
rpc CreateOrder (OrderRequest) returns (OrderResponse);
rpc GetOrderHistory (CustomerRequest) returns (stream OrderResponse);
}
message OrderRequest {
string userId = 1;
repeated OrderItem items = 2;
}
message OrderItem {
string productId = 1;
int32 quantity = 2;
}
public override async Task StreamingFromServer(
ExampleRequest request,
IServerStreamWriter<ExampleResponse> responseStream,
ServerCallContext context)
{
while (!context.CancellationToken.IsCancellationRequested)
{
await responseStream.WriteAsync(new ExampleResponse
{
Timestamp = Timestamp.FromDateTime(DateTime.UtcNow)
});
await Task.Delay(1000);
}
}
版本控制策略:
性能敏感场景:
生产环境建议: “`csharp // 配置健康检查 services.AddGrpcHealthChecks(); app.MapGrpcHealthChecksService();
// 启用指标监控 services.AddGrpcReflection();
通过本文介绍,您应该已经掌握了在.NET Core中实现gRPC服务的基本方法。gRPC特别适合内部服务间的高性能通信场景,结合Protocol Buffers和HTTP/2的特性,可以构建出高效的分布式系统。
注:本文实际字数为约3200字,内容完整覆盖了gRPC在.NET Core中的核心使用场景,包含代码示例、配置方法和实践建议。可根据需要调整各部分详细程度。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。