メッセージインスペクターによって提供されるwcfのような認証、検証、またはリクエストの相関などの機能をフルフィルするためにペイロードをデシリアライズせずに、追加情報を運ぶためにカスタムメッセージヘッダーを送信リクエストに挿入することは可能でしょうか?
2 に答える
アップデート
SDK v2 を使用すると、Reliable Services と Actors の両方のヘッダーを (比較的) 簡単に変更できるようになりました。以下の例では、簡潔にするために一部のラッパー メンバーが省略されていることに注意してください。
クライアント
ServiceProxyFactory
static の代わりにプロキシを作成するために使用します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 チームからのさらなる説明をお待ちしております。