我可以从集群外部但在同一本地网络中使用 RPC 调用无状态服务吗?
Can I call a stateless service with RPC from outside of a cluster but in the same local network?
2017 年 Visual Studio 在我的本地计算机上,我创建了基于 .NET Core 无状态服务模板的解决方案,并添加了 Microsoft.ServiceFabric.Services.Remoting.Runtime 包以通过 RPC 接受远程调用。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return this.CreateServiceRemotingInstanceListeners();
}
然后我在一个单独的项目中添加了接口ITestAccUp:
public interface ITestAccUp : IService
{
Task NotifyAsync();
}
我将接口的实现添加到无状态服务,并创建了一个项目,一个 .NET Core 控制台客户端到 运行 服务。控制台将 运行 在集群之外。
static void Main(string[] args)
{
ITestAccUp testAccUpClient = ServiceProxy.Create<ITestAccUp>(new Uri("fabric:/SFAccountUpTest/Stateless1"));
testAccUpClient.NotifyAsync().Wait();
}
但是,当我 运行 它时,我得到了错误 "InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'IFabricTestManagementClient4'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B96AA7D4-ACC0-4814-89DC-561B0CBB6028}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).",
尽管命名应用结构:/SFAccountUpTest/Stateless1 似乎已启动并且 运行ning.
我想问题是 RPC 调用只是为了调用 SF 集群内部的服务,而不是外部。是否可以在集群外进行 RPC 调用,或者是否需要构建某种网络 API 来进行服务调用?
只要您在同一个网络上,就可以使用 SF Remoting 从其他应用程序调用服务和演员。例如,请参阅 this demo 项目,该项目出于测试目的这样做。
确保您使用同一个 DLL 来保存来自客户端和服务项目的接口定义。 (它的工作方式不同于 WCF,后者可以通过使用 wsdl 独立于服务生成代理。)
也许您 运行 遇到了问题,例如 this one, or this 一个。
我意识到这个问题有点老了,但我解决这个问题的方法是确保我使用的是 "V2" 远程处理堆栈 (details here)
基本上您需要编辑 ServiceManifest.xml 以将其用作端点:
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpointV2" />
</Endpoints>
</Resources>
并将 [assembly]
属性添加到您的远程接口(在 namespace
之上)。
示例:
...
using Microsoft.ServiceFabric.Services.Remoting;
using Microsoft.ServiceFabric.Services.Remoting.FabricTransport;
[assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2, RemotingClientVersion = RemotingClientVersion.V2)]
namespace ClassLibrary1
{
public interface IMyService : IService
{
...
2017 年 Visual Studio 在我的本地计算机上,我创建了基于 .NET Core 无状态服务模板的解决方案,并添加了 Microsoft.ServiceFabric.Services.Remoting.Runtime 包以通过 RPC 接受远程调用。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return this.CreateServiceRemotingInstanceListeners();
}
然后我在一个单独的项目中添加了接口ITestAccUp:
public interface ITestAccUp : IService
{
Task NotifyAsync();
}
我将接口的实现添加到无状态服务,并创建了一个项目,一个 .NET Core 控制台客户端到 运行 服务。控制台将 运行 在集群之外。
static void Main(string[] args)
{
ITestAccUp testAccUpClient = ServiceProxy.Create<ITestAccUp>(new Uri("fabric:/SFAccountUpTest/Stateless1"));
testAccUpClient.NotifyAsync().Wait();
}
但是,当我 运行 它时,我得到了错误 "InvalidCastException: Unable to cast COM object of type 'System.__ComObject' to interface type 'IFabricTestManagementClient4'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{B96AA7D4-ACC0-4814-89DC-561B0CBB6028}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).", 尽管命名应用结构:/SFAccountUpTest/Stateless1 似乎已启动并且 运行ning.
我想问题是 RPC 调用只是为了调用 SF 集群内部的服务,而不是外部。是否可以在集群外进行 RPC 调用,或者是否需要构建某种网络 API 来进行服务调用?
只要您在同一个网络上,就可以使用 SF Remoting 从其他应用程序调用服务和演员。例如,请参阅 this demo 项目,该项目出于测试目的这样做。
确保您使用同一个 DLL 来保存来自客户端和服务项目的接口定义。 (它的工作方式不同于 WCF,后者可以通过使用 wsdl 独立于服务生成代理。)
也许您 运行 遇到了问题,例如 this one, or this 一个。
我意识到这个问题有点老了,但我解决这个问题的方法是确保我使用的是 "V2" 远程处理堆栈 (details here)
基本上您需要编辑 ServiceManifest.xml 以将其用作端点:
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpointV2" />
</Endpoints>
</Resources>
并将 [assembly]
属性添加到您的远程接口(在 namespace
之上)。
示例:
...
using Microsoft.ServiceFabric.Services.Remoting;
using Microsoft.ServiceFabric.Services.Remoting.FabricTransport;
[assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2, RemotingClientVersion = RemotingClientVersion.V2)]
namespace ClassLibrary1
{
public interface IMyService : IService
{
...