2017-01-14 16 views
1

サービスファブリッククラスタ内のあるアプリケーションから別のアプリケーションまたはサービスにサービスまたはアクターを呼び出すことは可能ですか?私は(適切なウリでActorProxy.Createを使用して)しようと試みたとき、私は「いいえMethodDispatcherがインターフェイスのために発見された」クラスタ内の他のアプリケーションからのサービスの呼び出し

答えて

5

を持ってはい、それは可能です。サービス(またはActorService)に適切なUriがあれば、サービスまたは俳優を定義するインタフェースを持つアセンブリにアクセスできます。同じアプリケーション内からService/Actorを呼び出すのと大きく異なるはずはありません。 enabled security for your serviceを持っていれば、交換用の証明書もセットアップする必要があります。

私は単純なサービスが定義されているかのように:

public interface ICalloutService : IService 
{ 
    Task<string> SayHelloAsync(); 
} 

internal sealed class CalloutService : StatelessService, ICalloutService 
{ 
    public CalloutService(StatelessServiceContext context) 
     : base(context) { } 

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners() 
    { 
     yield return new ServiceInstanceListener(this.CreateServiceRemotingListener); 
    } 

    public Task<string> SayHelloAsync() 
    { 
     return Task.FromResult("hello"); 
    } 
} 

とシンプルな俳優:

public interface ICalloutActor : IActor 
{ 
    Task<string> SayHelloAsync(); 
} 

[StatePersistence(StatePersistence.None)] 
internal class CalloutActor : Actor, ICalloutActor 
{ 
    public CalloutActor(ActorService actorService, ActorId actorId) 
     : base(actorService, actorId) {} 

    public Task<string> SayHelloAsync() 
    { 
     return Task.FromResult("hello"); 
    } 
} 

このようなアプリケーションで実行されている。そして、

Service Fabric Explorer

別のアプリケーションから呼び出すことができますw同じクラスタithin:

 // Call the service 
     var calloutServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutService"); 
     var calloutService = ServiceProxy.Create<ICalloutService>(calloutServiceUri); 
     var serviceHello = await calloutService.SayHelloAsync(); 

     // Call the actor 
     var calloutActorServiceUri = new Uri(@"fabric:/ServiceFabric.SO.Answer._41655575/CalloutActorService"); 
     var calloutActor = ActorProxy.Create<ICalloutActor>(new ActorId(DateTime.Now.Millisecond), calloutActorServiceUri); 
     var actorHello = await calloutActor.SayHelloAsync(); 

をあなたがサービスをクリックし、名前を見ればあなたがサービスファブリックエクスプローラの右ウリを見つけることができます。デフォルトでは、サービスのUriはfabric:/{applicationName}/{serviceName}です。

外部サービスから呼び出しサービスへのインターフェイスはどのようにして得られますか?呼び出すサービスのためにビルドされた.exeを参照するか、インターフェイスを含むアセンブリをNuGetパッケージとしてパッケージ化し、プライベートフィードを置くことができます。

これを行わずに、Visual Studioソリューション間でコードを共有するだけで、Service Fabricはまったく同じシグネチャを共有していても、これらが2つの異なるインターフェイスだとみなします。サービスの場合は、NotImplementedExceptionは「インターフェイスID '{xxxxxxxx}」はオブジェクト' {サービス} 'によって実装されていません。俳優の場合はKeyNotfoundExceptionと表示されます。「MethodDispatcherが見つかりませんインタフェースID ' - {xxxxxxxxxx}' '

したがって、問題を解決するには、呼び出す外部アプリケーションで呼び出すアプリケーション内の同じアセンブリを参照してください。

+1

可能ですが、良い方法ではありません。私はそれをデザインの匂いと考えるでしょう。ベストプラクティスのために、これらのSFアプリケーションはAPIを介して通信する必要があります。 – alltej

+0

既知のプロトコルを介してサービスと通信するTcp/fabricと既知のインタフェース(公開されたサービスインタフェース)は、APIと通信する方法です。あなたのクライアントがクラスタ内の他のアプリケーションであることを知っていれば、HTTPを介してAPIを公開することとは異なるとは思わないし、エンドポイントのSwaggerドキュメントを見てみましょう。私はあなたのアーキテクチャに依存していると言いますが、これらのサービスは、他のアプリケーションサービスが使用するさまざまな共通機能を提供する内部の「コア」サービスである可能性があります。その場合は、ファブリックトランスポートを使用することが設計上の問題ではないと言います。 – yoape

関連する問題