Как добавить заголовок сообщения в запрос при использовании клиента по умолчанию из сервисной фабрики Azure?
Мне интересно, можно ли добавить пользовательский заголовок сообщения в исходящий запрос для переноса дополнительной информации без десериализации полезной нагрузки для полного выполнения таких функций, как аутентификация, проверка или сопоставление запроса, такого как wcf, предоставляемого с помощью messagesinspector?
2 ответа
Обновить
С SDK v2 вы теперь (относительно) можете легко изменять заголовки как надежных служб, так и субъектов. Обратите внимание, что в приведенных ниже примерах некоторые элементы-оболочки были опущены для краткости.
клиент
Мы используем ServiceProxyFactory
создавать прокси вместо статических ServiceProxy
, Тогда мы можем обернуть IServiceRemotingClientFactory
а также IServiceRemotingClient
и перехватывать сервисные звонки. То же самое можно сделать с ActorProxyFactory
, Обратите внимание, что это переопределяет поведение атрибутов, таких как WcfServiceRemotingProviderAttribute
, поскольку мы явно указываем клиентскую фабрику сами.
_proxyFactory = new ServiceProxyFactory(c => new ServiceRemotingClientFactoryWrapper(
// we can use any factory here
new WcfServiceRemotingClientFactory(callbackClient: c)));
private class ServiceRemotingClientFactoryWrapper : IServiceRemotingClientFactory
{
private readonly IServiceRemotingClientFactory _inner;
public ServiceRemotingClientFactoryWrapper(IServiceRemotingClientFactory inner)
{
_inner = inner;
}
public async Task<IServiceRemotingClient> GetClientAsync(Uri serviceUri, ServicePartitionKey partitionKey, TargetReplicaSelector targetReplicaSelector,
string listenerName, OperationRetrySettings retrySettings, CancellationToken cancellationToken)
{
var client = await _inner.GetClientAsync(serviceUri, partitionKey, targetReplicaSelector, listenerName, retrySettings, cancellationToken).ConfigureAwait(false);
return new ServiceRemotingClientWrapper(client);
}
}
private class ServiceRemotingClientWrapper : IServiceRemotingClient
{
private readonly IServiceRemotingClient _inner;
public ServiceRemotingClientWrapper(IServiceRemotingClient inner)
{
_inner = inner;
}
public Task<byte[]> RequestResponseAsync(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
{
// use messageHeaders.AddHeader() here
return _inner.RequestResponseAsync(messageHeaders, requestBody);
}
public void SendOneWay(ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
{
// use messageHeaders.AddHeader() here
_inner.SendOneWay(messageHeaders, requestBody);
}
}
сервер
Наследовать от ServiceRemotingDispatcher
а также ActorServiceRemotingDispatcher
изучить заголовки.
class CustomServiceRemotingDispatcher : ServiceRemotingDispatcher
{
public override async Task<byte[]> RequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody)
{
// read messageHeaders here
// or alternatively put them in an AsyncLocal<T> scope
// so they can be accessed down the call chain
return base.RequestResponseAsync(requestContext, messageHeaders, requestBody);
}
}
Чтобы использовать этот класс, нам снова нужно переопределить ServiceRemotingProviderAttribute
путем непосредственного создания слушателя связи:
class MyService : StatelessService
{
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher());
}
}
Я задал тот же вопрос на форуме MSDN несколько недель назад, однако ответа там не получил.
Я изучил исходный код клиентской библиотеки и не нашел способа добавить заголовки. Боюсь, единственный способ - добавить их как часть вызова метода. Это можно сделать, используя классы запросов в качестве параметров метода и используя для них наследование. (например, класс RequestBase с заголовками [Authorization, ClientInfo, ...]). Затем вы должны убедиться, что эти заголовки установлены для каждого запроса, обернув все вызовы или установив его вручную.
Будем весьма благодарны за дальнейшие разъяснения от команды Service Fabric.