Azure service fabric 通过http从服务结构公开WCF restful服务
我试图通过http公开一个基于WCF的restful服务,但迄今为止没有成功。我先在我本地的机器上试一下,证明它能用。我发现有人建议我删除本地群集,然后以管理员身份从SF SDK文件夹手动运行此powershell命令,以使用机器名绑定重新创建它:。\DevClusterSetup.ps1-UseMachineName 它成功地创建了集群。我可以使用SF资源管理器,并在集群清单中看到节点列表中的条目显示机器名而不是本地主机。这看起来不错 但我注意到的第一个问题是,如果我通过SF Explorer向下扩展到我的应用程序运行的节点,我会看到一个端点条目,但URL不是我所期望的。我看到: 即使我有端点设置,这也是我应该看到的吗?我不希望路径中出现guid和其他数字。这让我怀疑SF没有将我的服务视为可公开访问的服务,而可能只是设置为在应用程序内进行内部访问?如果我深入查看我的服务清单,我会发现这一点:Azure service fabric 通过http从服务结构公开WCF restful服务,azure-service-fabric,Azure Service Fabric,我试图通过http公开一个基于WCF的restful服务,但迄今为止没有成功。我先在我本地的机器上试一下,证明它能用。我发现有人建议我删除本地群集,然后以管理员身份从SF SDK文件夹手动运行此powershell命令,以使用机器名绑定重新创建它:。\DevClusterSetup.ps1-UseMachineName 它成功地创建了集群。我可以使用SF资源管理器,并在集群清单中看到节点列表中的条目显示机器名而不是本地主机。这看起来不错 但我注意到的第一个问题是,如果我通过SF Explorer
<Resources>
<Endpoints>
<Endpoint Name="ResolverEndpoint" Protocol="http" Type="Input" Port="80" />
</Endpoints>
</Resources>
但我如何知道服务本身是否映射到它?当我使用上面疯狂的长url并尝试我的服务的一个简单方法时,我得到了http 202响应,但没有预期的响应数据。如果我将方法名更改为一个不存在的名称,我会得到相同的结果,而不是预期的HTTP404。我尝试使用我的机器名和本地主机。同样的结果
很明显我做错了什么。下面是我的CreateServiceInstanceListeners覆盖。在其中,您可以看到我使用“ResolverEndpoint”作为端点资源名称,该名称与服务清单匹配:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] { new ServiceInstanceListener((context) =>
new WcfCommunicationListener<IResolverV2>(
serviceContext: context,
wcfServiceObject: new ResolverServiceV2(),
listenerBinding: new WebHttpBinding(WebHttpSecurityMode.None),
endpointResourceName: "ResolverEndpoint"
)
)};
}
受保护的重写IEnumerable CreateServiceInstanceListeners()
{
返回新[]{new ServiceInstanceListener((上下文)=>
新的WcfCommunicationListener(
serviceContext:context,
wcfServiceObject:new ResolverServiceV2(),
listenerBinding:新的WebHttpBinding(WebHttpSecurityMode.None),
endpointResourceName:“ResolverEndpoint”
)
)};
}
我做错了什么?服务清单中指定的端点资源由流程中使用相同端点资源名称的所有副本侦听器共享。因此,如果您的服务有多个分区,那么来自不同分区的多个副本可能会在同一进程中结束。为了区分发往不同分区的消息,侦听器将分区ID和其他实例GUID添加到路径中 如果您打算使用单例分区服务,并且知道在同一进程中不会有多个副本,那么您可以直接向侦听器提供要在其上打开的EndpointAddress。使用CodePackageActivationContext API从NodeContext中的端点资源名称、节点名称或IP地址获取端口,然后提供希望侦听器打开的路径 以下是WcfCommunicationListener中构造侦听地址的代码
private static Uri GetListenAddress(
ServiceContext serviceContext,
string scheme,
int port)
{
return new Uri(
string.Format(
CultureInfo.InvariantCulture,
"{0}://{1}:{2}/{5}/{3}-{4}",
scheme,
serviceContext.NodeContext.IPAddressOrFQDN,
port,
serviceContext.PartitionId,
serviceContext.ReplicaOrInstanceId,
Guid.NewGuid()));
}
请注意,现在一个节点上只能有一个应用程序、一个服务和一个分区,当您在本地测试时,请将该服务的实例计数保持为1。在实际集群中部署时,您可以使用-1实例计数。以下是一种让它工作的方法:
对代码的基本更改是使用集群的公共名称作为端点URL,并在该端点上添加一个
WebHttpBehavior
行为。因此,您将向我展示WcfCommunicationListener当前的工作方式。这很有趣,但我真的在寻找如何让它为我工作的指导,这并不明显。如何使其不将分区/副本信息附加到地址?我需要重写Wcf侦听器并更改OpenAsymc方法吗?VipuIM是一个超级简单的ICalculator类型示例应用程序,它公开了一个基于Wcf的公共WebApi,这将使它更容易理解。你能帮我把我们可以放进github供其他人使用的东西放在一起吗?请随意开始一个示例并发送给我代码链接。使用侦听器的构造函数直接获取端点地址,而不是传递端点资源名。是的,这看起来非常像我在Vipul帮助下编写的内容。我在您的中看到的唯一区别是HostFromConfig()逻辑。为什么您认为这是必要的,而不是始终依赖context.NodeContext.IPAddressOrFQDN?我已经部署到一个Azure集群,但没有这种逻辑,是否存在您认为必要的场景?不,您是对的。更改ServiceInstanceListener,使其不使用endpointResourceName,但使用address就足够了。