从群集中的其他应用程序调用服务

时间:2017-01-14 22:17:05

标签: azure-service-fabric

是否可以在Service Fabric Cluster中将服务或参与者从一个应用程序调用到另一个应用程序?当我尝试(使用正确的Uri使用ActorProxy.Create)时,我得到了“没有为界面找到MethodDispatcher”

1 个答案:

答案 0 :(得分:6)

是的,可能。只要您拥有对服务(或ActorService)的正确Uri,您就可以访问具有定义服务或演员的接口的程序集,它与调用服务/ 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

然后,您可以从同一群集中的其他应用程序调用它:

        // 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();

如果单击该服务并查看名称,则可以在Service Fabric Explorer中找到正确的Uri。默认情况下,服务的Uri为:fabric:/{applicationName}/{serviceName}

唯一棘手的部分是如何获得从外部服务到呼叫服务的接口?您可以简单地引用要调用的服务的内置.exe,或者您可以将包含该接口的程序集打包为NuGet包并放入私有源。

如果你不这样做而只是在Visual Studio解决方案之间共享代码,Service Fabric会认为这些是两个不同的接口,即使它们共享完全相同的签名。如果您为服务执行此操作,则会得到NotImplementedException说“接口ID'{xxxxxxxx}'未由对象'{service}'”实现,如果您为Actor执行此操作,则会得到{{1} }说“没有为接口ID'找到MethodDispatcher' - {xxxxxxxxxx}'”。

因此,要解决您的问题,请确保引用要在正在调用的外部应用程序中调用的应用程序中的同一程序集。