我想知道可以将自定义消息头注入传出请求以携带附加信息而无需反序列化有效负载以完成填充功能,如身份验证,验证或请求的相关性,如通过messagesinspector提供的wcf?
更新
使用SDK v2,您现在可以(相对)轻松地修改Reliable Services和Actors的标头.请注意,在下面的示例中,为简洁起见,省略了一些包装器成员.
客户
我们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 TaskGetClientAsync(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 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 TaskRequestResponseAsync(IServiceRemotingRequestContext requestContext, ServiceRemotingMessageHeaders messageHeaders, byte[] requestBody) { // read messageHeaders here // or alternatively put them in an AsyncLocal scope // so they can be accessed down the call chain return base.RequestResponseAsync(requestContext, messageHeaders, requestBody); } }
要使用此类,我们需要重写ServiceRemotingProviderAttribute
直接创建通信侦听器:
class MyService : StatelessService { protected override IEnumerableCreateServiceInstanceListeners() { yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher()); } }