使用Azure服务结构的默认客户端时如何向请求添加邮件头?

Xia*_*ong 13 .net azure azure-service-fabric

我想知道可以将自定义消息头注入传出请求以携带附加信息而无需反序列化有效负载以完成填充功能,如身份验证,验证或请求的相关性,如通过messagesinspector提供的wcf?

Eli*_*bel 20

更新

使用SDK v2,您现在可以(相对)轻松地修改Reliable Services和Actors的标头.请注意,在下面的示例中,为简洁起见,省略了一些包装器成员.

客户

我们ServiceProxyFactory用来创建代理而不是静态ServiceProxy.然后我们可以包装IServiceRemotingClientFactoryIServiceRemotingClient拦截服务调用.同样可以做到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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

服务器

继承ServiceRemotingDispatcherActorServiceRemotingDispatcher检查标头.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用此类,我们需要重写ServiceRemotingProviderAttribute直接创建通信侦听器:

class MyService : StatelessService
{
     protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
     {
          yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher());
     }
}
Run Code Online (Sandbox Code Playgroud)