Сервер и клиент в .NET: Grpc.AspNetCore, Grpc.Net.Client
↑ 5.2 gRPC · ← Предыдущая · → Следующая
Зачем это на собесе
Практическая часть: как поднять gRPC-сервис и вызывать его из другого сервиса.
Объяснение
Сервер
// Program.cs
builder.Services.AddGrpc(o => o.Interceptors.Add<ExceptionInterceptor>());
app.MapGrpcService<OrderGrpcService>();
public class OrderGrpcService(IOrderService orders) : OrderService.OrderServiceBase
{
public override async Task<OrderReply> GetOrder(GetOrderRequest req, ServerCallContext ctx)
{
var order = await orders.FindAsync(Guid.Parse(req.Id), ctx.CancellationToken)
?? throw new RpcException(new Status(StatusCode.NotFound, "order not found"));
return new OrderReply { Id = order.Id.ToString(), Customer = order.Customer };
}
}Клиент
builder.Services.AddGrpcClient<OrderService.OrderServiceClient>(o => o.Address = new Uri("https://orders:8443"))
.AddStandardResilienceHandler();
public class Checkout(OrderService.OrderServiceClient client)
{
public async Task<OrderReply> LoadAsync(string id, CancellationToken ct)
=> await client.GetOrderAsync(new GetOrderRequest { Id = id }, deadline: DateTime.UtcNow.AddSeconds(3), cancellationToken: ct);
}AddGrpcClient использует HttpClientFactory: пул соединений и ретраи настраиваются так же. Внутри сети без TLS используйте h2c (Http2UnencryptedSupport).
Нюансы и подводные камни
- Сервис gRPC создаётся на вызов (transient); состояние храните в DI, не в полях.
- Исключения превращайте в
RpcExceptionс корректнымStatusCodeв interceptor. - Клиент должен передавать
CancellationTokenи deadline. - Kestrel: HTTP/2 требует TLS или явной настройки
Http2для порта. - Модели protobuf — не доменные: маппьте их на границе.
Практика
- Поднимите gRPC-сервис и клиент в двух проектах.
- Добавьте interceptor для логирования и преобразования исключений.
- Включите gRPC reflection и проверьте через
grpcurl.
Вопросы с ответами
Как в gRPC вернуть ошибку?
Бросить
RpcExceptionсStatusCodeи сообщением/метаданными.
Нужно ли создавать канал на каждый вызов?
Нет: канал переиспользуют (через
AddGrpcClientили singleton).