服务结构服务远程处理 [英] Service Fabric Service Remoting

查看:46
本文介绍了服务结构服务远程处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近几周我一直在从Cloud Services迁移到Service Fabric,并且在两个服务之间使用Remoting遇到了一些绊脚石.

I've been migrating from Cloud Services to Service Fabric the last few weeks and have been running into a few stumbling blocks using Remoting between 2 services.

我一直在使用有关服务远程处理的官方文档和示例代码,尤其是我正在尝试使此处概述的示例起作用:

I've been using the official documentation and sample code on Service Remoting and in particular I'm trying to get the sample outlined here to work:

https://docs.microsoft.com/zh-CN/azure/service-fabric/service-fabric-reliable-services-communication-remoting

我有2个服务.一个名为"RemoteService" ,另一个名为"CallerService" .两者均来自默认的无状态服务项目.

I have 2 services. One is named "RemoteService" and the other is named "CallerService". Both are derived from a default Stateless Service project.

"RemoteService" "CallerService" 项目中,我都添加了以下接口来描述它们之间的服务合同:

In both the "RemoteService" and "CallerService" projects I have added the following Interface to describe the service contract between them:

public interface IMyService : IService
{
    Task<string> HelloNameAsync(string name);
}

"RemoteService" 中,我在RemoteService类中创建了关联的方法

In the "RemoteService" I've created asociated method within the RemoteService class

public Task<string> HelloNameAsync(string name)
{
    return Task.FromResult("Hello " + name + "!");
}

我还使用以下内容覆盖了 CreateServiceInstanceListeners

I also override CreateServiceInstanceListeners with the following

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new[] { new ServiceInstanceListener(context => this.CreateServiceRemotingListener(context)) };
}

在我尝试连接的"CallerService" 中,使用以下命令呼叫"RemoteService":

In my "CallerService" when I attempt to connect make the call to the "RemoteService" with the following:

IMyService helloNameClient = ServiceProxy.Create<IMyService>(new Uri("fabric:/Application/RemoteService"));
string message = await helloNameClient.HelloNameAsync("Luke");

我得到这个例外

InnerException = {"Interface id '1994370306' is not implemented by object 'RemoteService.RemoteService'"}

我用细齿梳检查了这个样品,并确保我已经准备好一切.我已经阅读了有关设置端点并将您的服务注册到服务目录中的信息,但是据我了解,这些端点是针对外部服务的,而Remoting文档中并未提及要求这样做.

I've gone over this sample with a fine tooth comb and am sure that I have everything in place as it should be. I've read about setting up endpoints and registering your services into a service directory, but from what I understand those are for external services and the Remoting documentation does not mention requiring this.

更新:

以下是声明RemoteService类的方式:

Here is how the RemoteService class is declared:

internal sealed class RemoteService : StatelessService, IMyService

更新2

这是这两种服务的Settings.xml外观.这些是项目开箱即用的默认设置.我没有添加或删除任何东西.我还想指出,我正在本地服务结构上运行所有这些操作.

Here is what the Settings.xml looks like for both services. These are the default settings that come out of the box with the project. I did not add or remove anything. I also want to note that I am running all of this on my local service fabric.

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <!-- Add your custom configuration sections and parameters here -->
  <!--
  <Section Name="MyConfigSection">
    <Parameter Name="MyParameter" Value="Value1" />
  </Section>
  -->
</Settings>

推荐答案

声明服务接口的程序集需要与客户端共享,您不能在客户端重新创建相同的接口.当Service Fabric设置通信时,它会根据服务使用的实际程序集建立接口及其方法的映射.

The assembly the service interface is declared in needs to be shared with the client, you cannot recreate an identical interface on the client side. When Service Fabric sets up the communication it builds up a map of the interface and it's methods from the actual assembly used by the service.

根据您的描述,您似乎在服务和客户端项目中都声明了相同的接口?如果是这样,那就解决了.

Based on your description, it looks like you are declaring an identical interface in both service and client project? If so, then this is the fix.

SO:从群集中的其他应用程序调用服务: 唯一棘手的部分是如何从外部服务到呼叫服务获得接口?您可以简单地引用要调用的服务的内置.exe,也可以将包含接口的程序集打包为NuGet程序包,然后放入私有供稿.

From SO: Calling services from other application in the cluster: The only tricky part is how do you get the interface from the external service to your calling service? You could simply reference the built .exe for the service you wish to call or you could package the assembly containing the interface as a NuGet package and put on a private feed.

如果您不这样做,而只是在Visual Studio解决方案之间共享代码,则Service Fabric会认为这是两个不同的接口,即使它们共享完全相同的签名也是如此.如果为服务执行此操作,则会收到NotImplementedException,指出接口ID'{xxxxxxxx}'不是由对象'{service}'实现的".如果为Actor执行此操作,则会得到KeyNotfoundException,其内容为:找不到用于接口ID'-{xxxxxxxxxx}'".

If you don't do this and you instead just share the code between your Visual Studio solutions the Service Fabric will think these are two different interfaces, even if they share the exact same signature. If you do it for a Service you get an NotImplementedException saying "Interface id '{xxxxxxxx}' is not implemented by object '{service}'" and if you do it for an Actor you get an KeyNotfoundException saying "No MethodDispatcher is found for interface id '-{xxxxxxxxxx}'".

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

So, to fix your problem, make sure you reference the same assembly that is in the application you want to call in the external application that is calling.

这篇关于服务结构服务远程处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆