2015-12-08 7 views
9

私は可能性がありますメッセージのインスペクタによって提供されるwcfのような要求の認証、検証または相関のような機能をfullfillにペイロードを非直列化せずに追加情報を運ぶために発信メッセージにカスタムメッセージヘッダーを挿入することができますか?Azureサービスファブリックのデフォルトクライアントを使用している場合、リクエストにメッセージヘッダーを追加するにはどうすればよいですか?

答えて

14

更新

あなたは今、(比較的)簡単に信頼性の高いサービスと俳優の両方のヘッダを変更することができます。以下の例では、簡潔にするためにいくつかのラッパーメンバーが省略されています。私たちは、プロキシの代わりに、静的ServiceProxyを作成するためにServiceProxyFactoryを使用

クライアント

。その後、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); 
     } 
    } 

サーバー

継承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); 
    } 
} 

このクラスを使用するには、再び我々は直接通信リスナー作成することにより、ServiceRemotingProviderAttributeをオーバーライドする必要があります。idは、クライアントのソースコードをお探し

class MyService : StatelessService 
{ 
    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() 
    { 
      yield return new ServiceInstanceListener(context => new WcfServiceRemotingListener(context, new CustomServiceRemotingDispatcher()); 
    } 
} 
+0

私は同じ方向に行く、あなたのコードの例明確な助けたくさん。しかし、Microsoftは、このようなユースケースを可能にするために、同じメッセージハンドラメカニズムをMicrosoftに提供したいと考えています。 – Xiangdong

+0

ServiceInstanceListenerには、WcfServiceRemotingListenerと同じ方法で、dispatcherのコンストラクタパラメータがありません。 Remotingを使用する場合、ディスパッチャをどのように追加しますか? – SondreB

+0

ServiceInstanceListenerはIServiceRemotingMessageHandlerではなくICommunicationListenerを受け取り、そのインターフェイスにはメッセージヘッダーを返すメソッドがありません。 – SondreB

0

私は数週間前にthe same question on the MSDN forumに尋ねましたが、私はそこに返答しませんでした。

クライアントライブラリのソースコードを調べましたが、ヘッダーを追加する方法が見つかりませんでした。私は唯一の方法はメソッド呼び出しの一部としてそれらを追加することだと思います。これは、メソッド・パラメーターとしてrequest-classを使用し、それらに継承を使用することによって実行できます。 (ヘッダ[Authorization、ClientInfo、...]を含むRequestBaseクラス)。これらのヘッダーは、すべての呼び出しをラップするか、または手動で設定することによって、すべての要求に対して設定されていることを確認する必要があります。

サービスファブリックチームのさらなる明確化が大いに評価されます。 SDK v2では

+0

を?私はAPIをチェックアウトしました。そこには、送信要求にカスタムヘッダーを追加する方法があると思うServiceRemotingHeadersクラスがあります。さらに、クライアントはwcfを使用して通信を行っているようです。そうであれば、messageinspectorを開発者に公開することが実現可能であるはずです。 – Xiangdong

+0

@ Xiangdong私はILSpyでMicrosoft.ServiceFabric.Services.dllを見ました。 ServiceRemotingHeadersは行く方法のようです、はい。しかし、私はそれらを外部から設定する方法を見つけていません。 ServiceProxy.InvokeAsync()は要求を開始する場所で、内部的にServiceRemotingMessageHeaders変数を作成し、それを下流のServicePartitionClientに渡します。しかし、多分私は何かを逃した... –

関連する問題