【发布时间】:2017-01-14 22:17:05
【问题描述】:
是否可以在 Service Fabric 群集中将服务或参与者从一个应用程序调用到另一个应用程序?当我尝试(使用具有正确 Uri 的 ActorProxy.Create)时,我得到了“No MethodDispatcher is found for interface”
【问题讨论】:
是否可以在 Service Fabric 群集中将服务或参与者从一个应用程序调用到另一个应用程序?当我尝试(使用具有正确 Uri 的 ActorProxy.Create)时,我得到了“No MethodDispatcher is found for interface”
【问题讨论】:
是的,有可能。只要您拥有服务(或 ActorService)的正确 Uri并且您可以使用定义您的服务或参与者的接口访问程序集,它应该与调用服务/参与者没有太大区别从同一个应用程序中。如果您有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");
}
}
在这样的应用程序中运行:
然后您可以从同一个集群中的另一个应用程序调用它:
// 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 执行此操作,您会收到 KeyNotfoundException 说“否为接口 id '-{xxxxxxxxxx}' 找到 MethodDispatcher。
因此,要解决您的问题,请确保您在正在调用的外部应用程序中引用您要调用的应用程序中的相同程序集。
【讨论】: