Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Автор: Джеймс Ньютон-Кинг (James Newton-King)
Интеграция gRPC с HttpClientFactory обеспечивает централизованный способ создания клиентов gRPC. Его можно использовать в качестве альтернативы настройке отдельных экземпляров клиента gRPC. Интеграция производства доступна в пакете NuGet Grpc.Net.ClientFactory.
Производство обеспечивает следующие преимущества:
- Предоставляет централизованное место для настройки логических экземпляров клиента gRPC.
- Управляет жизненным циклом базового объекта
HttpClientMessageHandler. - Автоматическое распространение крайнего срока и отмены в службе gRPC на платформе ASP.NET Core.
Регистрация клиентов gRPC
Для регистрации клиента gRPC можно использовать универсальный метод расширения AddGrpcClient в экземпляре WebApplicationBuilder в точке входа приложения в Program.cs, указав класс типизированного клиента gRPC и адрес службы:
builder.Services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Тип клиента gRPC регистрируется в системе внедрения зависимостей (DI) как временный. Клиент теперь может быть внедрен и использоваться напрямую в типах, созданных с использованием DI. Автоматически внедрять клиенты gRPC можно в контроллеры MVC ASP.NET Core, концентраторы SignalR и службы gRPC:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
public override async Task SayHellos(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
// Forward the call on to the greeter service
using (var call = _client.SayHellos(request))
{
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
await responseStream.WriteAsync(response);
}
}
}
}
Настройка HttpHandler
HttpClientFactory создает объект HttpMessageHandler, используемый клиентом gRPC. С помощью стандартных методов HttpClientFactory можно добавлять ПО промежуточного слоя для исходящих запросов или настраивать базовый обработчик HttpClientHandler объекта HttpClient:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Дополнительные сведения см. в статье Выполнение HTTP-запросов с помощью IHttpClientFactory.
Настройка перехватчиков
Перехватчики gRPC можно добавить к клиентам с помощью метода AddInterceptor.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Предыдущий код:
- Регистрирует тип
GreeterClient. - Настраивает
LoggingInterceptorдля этого клиента.LoggingInterceptorсоздается один раз и совместно используется экземплярамиGreeterClient.
По умолчанию перехватчик создается один раз и совместно используется клиентами. Это поведение можно переопределить, указав область при регистрации перехватчика. Фабрику клиента можно настроить на создание нового перехватчика для каждого клиента, указав InterceptorScope.Client.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
Создание перехватчиков с областью действия клиента полезно в том случае, когда перехватчику требуются службы с заданной областью или временно заданной областью от внедрения зависимостей.
Для отправки Authorization метаданных с каждым запросом можно использовать перехватчик gRPC или учетные данные канала. Дополнительные сведения о настройке проверки подлинности см. в разделе Создание токена носителя с помощью фабрики клиента gRPC.
Настройка канала
Дополнительную конфигурацию можно применить к каналу с помощью метода ConfigureChannel:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel передается экземпляр GrpcChannelOptions. Дополнительные сведения см. в разделе Настройка параметров клиента.
Примечание.
Некоторые свойства задаются в параметре GrpcChannelOptions перед выполнением обратного вызова ConfigureChannel:
-
HttpHandlerприсваивается результат из ConfigurePrimaryHttpMessageHandler. -
LoggerFactoryполучает значение ILoggerFactory, разрешаемое в процессе внедрения зависимостей.
Эти значения можно переопределить с помощью ConfigureChannel.
Аутентификационные данные вызова
Заголовок проверки подлинности можно добавить в вызовы gRPC с помощью метода AddCallCredentials:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddCallCredentials((context, metadata) =>
{
if (!string.IsNullOrEmpty(_token))
{
metadata.Add("Authorization", $"Bearer {_token}");
}
return Task.CompletedTask;
});
Дополнительные сведения о настройке учётных данных для вызова см. в разделе Токен Bearer с помощью фабрики клиента gRPC.
Распространение крайнего срока и отмены
С помощью метода EnableCallContextPropagation() у клиентов gRPC, созданных фабрикой в службе gRPC, можно настроить автоматическую передачу крайнего срока и токена отмены на дочерние вызовы. Метод расширения EnableCallContextPropagation() доступен в пакете NuGet Grpc.AspNetCore.Server.ClientFactory.
Распространение контекста вызова осуществляется путем считывания токена крайнего срока и отмены из текущего контекста запроса gRPC и его автоматического распространения на исходящие вызовы, выполняемые клиентом gRPC. Распространение контекста вызова — это отличный способ гарантировать передачу крайнего срока и отмены в сложных вложенных сценариях gRPC.
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
По умолчанию EnableCallContextPropagation вызывает ошибку, если клиент используется вне контекста вызова gRPC. Эта ошибка информирует о том, что контекст вызова для распространения отсутствует. Если вы хотите использовать клиент за пределами контекста вызова, подавите ошибку при настройке клиента с использованием SuppressContextNotFoundErrors:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Дополнительные сведения о крайних сроках и отмене RPC см. в статье Надежные службы gRPC с крайними сроками и отменой.
Именованные клиенты
Как правило, тип клиента gRPC регистрируется один раз, а затем внедряется непосредственно в конструктор типа через DI. Но есть сценарии, когда полезно иметь несколько конфигураций для одного клиента. Например, клиент, который выполняет вызовы gRPC с проверкой подлинности и без нее.
Несколько клиентов одинакового типа могут быть зарегистрированы путем присвоения каждому клиенту имени. Каждый именованный клиент может иметь собственную конфигурацию. Универсальный метод расширения AddGrpcClient имеет перегрузку, которая включает параметр имени:
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
builder.Services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
Предыдущий код:
- Дважды регистрирует тип
GreeterClient, указывая уникальное имя каждый раз. - Настраивает разные параметры для каждого именованного клиента. Регистрация
GreeterAuthenticatedдобавляет учетные данные в канал, чтобы вызовы gRPC, сделанные с их использованием, проходили аутентификацию.
В коде приложения создается именованный клиент gRPC с помощью GrpcClientFactory. Тип и имя требуемого клиента указываются с помощью универсального метода GrpcClientFactory.CreateClient:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
Дополнительные ресурсы
Интеграция gRPC с HttpClientFactory обеспечивает централизованный способ создания клиентов gRPC. Его можно использовать в качестве альтернативы настройке отдельных экземпляров клиента gRPC. Интеграция производства доступна в пакете NuGet Grpc.Net.ClientFactory.
Производство обеспечивает следующие преимущества:
- предоставляет центральное расположение для настройки логических экземпляров клиента gRPC;
- управляет временем существования базового объекта
HttpClientMessageHandler; - Автоматическое распространение срока выполнения и отмены в сервисе gRPC на платформе ASP.NET Core.
Регистрация клиентов gRPC
Для регистрации клиента gRPC можно использовать универсальный метод расширения AddGrpcClient в Startup.ConfigureServices, указав класс типизированного клиента gRPC и адрес службы:
services.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
});
Тип клиента gRPC регистрируется в системе внедрения зависимостей (DI) как временный. Клиент теперь может быть внедрен и использоваться напрямую в типах, созданных с использованием DI. Автоматически внедрять клиенты gRPC можно в контроллеры MVC ASP.NET Core, концентраторы SignalR и службы gRPC:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(Greeter.GreeterClient client)
{
_client = client;
}
public override async Task SayHellos(HelloRequest request,
IServerStreamWriter<HelloReply> responseStream, ServerCallContext context)
{
// Forward the call on to the greeter service
using (var call = _client.SayHellos(request))
{
await foreach (var response in call.ResponseStream.ReadAllAsync())
{
await responseStream.WriteAsync(response);
}
}
}
}
Настройка HttpHandler
HttpClientFactory создает объект HttpMessageHandler, используемый клиентом gRPC. С помощью стандартных методов HttpClientFactory можно добавлять ПО промежуточного слоя для исходящих запросов или настраивать базовый обработчик HttpClientHandler объекта HttpClient:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigurePrimaryHttpMessageHandler(() =>
{
var handler = new HttpClientHandler();
handler.ClientCertificates.Add(LoadCertificate());
return handler;
});
Дополнительные сведения см. в статье Выполнение HTTP-запросов с помощью IHttpClientFactory.
Настройка перехватчиков
Перехватчики gRPC можно добавить к клиентам с помощью метода AddInterceptor.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>();
Предыдущий код:
- Регистрирует тип
GreeterClient. - Настраивает
LoggingInterceptorдля этого клиента.LoggingInterceptorсоздается один раз и совместно используется экземплярамиGreeterClient.
По умолчанию перехватчик создается один раз и совместно используется клиентами. Это поведение можно переопределить, указав область при регистрации перехватчика. Фабрику клиента можно настроить на создание нового перехватчика для каждого клиента, указав InterceptorScope.Client.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.AddInterceptor<LoggingInterceptor>(InterceptorScope.Client);
Создание перехватчиков с областью действия клиента полезно в том случае, когда перехватчику требуются службы с заданной областью или временно заданной областью от внедрения зависимостей.
Для отправки Authorization метаданных с каждым запросом можно использовать перехватчик gRPC или учетные данные канала. Дополнительные сведения о настройке проверки подлинности см. в разделе Создание токена носителя с помощью фабрики клиента gRPC.
Настройка канала
Дополнительную конфигурацию можно применить к каналу с помощью метода ConfigureChannel:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
ConfigureChannel передается экземпляр GrpcChannelOptions. Дополнительные сведения см. в разделе Настройка параметров клиента.
Примечание.
Некоторые свойства задаются в параметре GrpcChannelOptions перед выполнением обратного вызова ConfigureChannel:
-
HttpHandlerприсваивается результат из ConfigurePrimaryHttpMessageHandler. -
LoggerFactoryполучает значение ILoggerFactory, разрешаемое в процессе внедрения зависимостей.
Эти значения можно переопределить с помощью ConfigureChannel.
Распространение крайнего срока и отмены
С помощью метода EnableCallContextPropagation() у клиентов gRPC, созданных фабрикой в службе gRPC, можно настроить автоматическую передачу крайнего срока и токена отмены на дочерние вызовы. Метод расширения EnableCallContextPropagation() доступен в пакете NuGet Grpc.AspNetCore.Server.ClientFactory.
Распространение контекста вызова осуществляется путем считывания токена крайнего срока и отмены из текущего контекста запроса gRPC и его автоматического распространения на исходящие вызовы, выполняемые клиентом gRPC. Распространение контекста вызова — это отличный способ гарантировать передачу крайнего срока и отмены в сложных вложенных сценариях gRPC.
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
По умолчанию EnableCallContextPropagation вызывает ошибку, если клиент используется вне контекста вызова gRPC. Эта ошибка информирует о том, что контекст вызова для распространения отсутствует. Если вы хотите использовать клиент за пределами контекста вызова, подавите ошибку при настройке клиента с использованием SuppressContextNotFoundErrors:
services
.AddGrpcClient<Greeter.GreeterClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation(o => o.SuppressContextNotFoundErrors = true);
Дополнительные сведения о крайних сроках и отмене RPC см. в статье Надежные службы gRPC с крайними сроками и отменой.
Именованные клиенты
Как правило, тип клиента gRPC регистрируется один раз, а затем внедряется непосредственно в конструктор типа через DI. Но есть сценарии, когда полезно иметь несколько конфигураций для одного клиента. Например, клиент, который выполняет вызовы gRPC с проверкой подлинности и без нее.
Несколько клиентов одинакового типа могут быть зарегистрированы путем присвоения каждому клиенту имени. Каждый именованный клиент может иметь собственную конфигурацию. Универсальный метод расширения AddGrpcClient имеет перегрузку, которая включает параметр имени:
services
.AddGrpcClient<Greeter.GreeterClient>("Greeter", o =>
{
o.Address = new Uri("https://localhost:5001");
});
services
.AddGrpcClient<Greeter.GreeterClient>("GreeterAuthenticated", o =>
{
o.Address = new Uri("https://localhost:5001");
})
.ConfigureChannel(o =>
{
o.Credentials = new CustomCredentials();
});
Предыдущий код:
- Дважды регистрирует тип
GreeterClient, указывая уникальное имя каждый раз. - Настраивает разные параметры для каждого именованного клиента. Регистрация
GreeterAuthenticatedдобавляет учетные данные в канал, чтобы вызовы gRPC, сделанные с их использованием, проходили аутентификацию.
В коде приложения создается именованный клиент gRPC с помощью GrpcClientFactory. Тип и имя требуемого клиента указываются с помощью универсального метода GrpcClientFactory.CreateClient:
public class AggregatorService : Aggregator.AggregatorBase
{
private readonly Greeter.GreeterClient _client;
public AggregatorService(GrpcClientFactory grpcClientFactory)
{
_client = grpcClientFactory.CreateClient<Greeter.GreeterClient>("GreeterAuthenticated");
}
}
Дополнительные ресурсы
ASP.NET Core