天蓝色服务结构 wcf 端点地址 net.tcp 而不是 http
Posted
技术标签:
【中文标题】天蓝色服务结构 wcf 端点地址 net.tcp 而不是 http【英文标题】:azure service fabric wcf endpoint address net.tcp instead of http 【发布时间】:2016-08-13 01:36:48 【问题描述】:尝试在服务结构中使用 wcf 设置有状态的可靠服务,我复制了以下示例代码:
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
return new[] new ServiceReplicaListener((context) =>
new WcfCommunicationListener<IService1>(
wcfServiceObject:this,
serviceContext:context,
endpointResourceName: "ServiceEndpoint",
listenerBinding: WcfUtility.CreateTcpListenerBinding()
)
);
在 ServiceManifest.xml 我已经声明了端点:
<Resources>
<Endpoints>
<Endpoint Name="ServiceEndpoint" Protocol="http" Port="8100" />
<Endpoint Name="ReplicatorEndpoint" />
</Endpoints>
</Resources>
但是当我部署到本地集群,并在 Service Fabric Explorer 中查看运行服务的节点时,端点有这个地址:
net.tcp://localhost:8100/455d1c74-7734-449b-a567-47b749b3b822/88af6851-0285-4989-b0aa-c0cbe8c2d06a-131056235989980581
如何获取 http 地址?
【问题讨论】:
关键是您的 listenerBinding 属性是使用 WcfUtility.CreateTcpListenerBinding() 分配的。我想这是目前唯一可能的方法,因为 WcfUtility 中没有其他方法,但是看看这个链接,也许它会对你有所帮助:azure.microsoft.com/en-us/documentation/articles/… 感谢您的回复,我怀疑是监听器绑定的问题。您引用的页面是我从中获取代码的地方:-)。我还没有找到任何其他关于在 wcf 中使用服务结构的文档。 【参考方案1】:在我的团队中,这些天我们一直在使用服务结构中的 wcf。首先,我们尝试使用 Microsoft.ServiceFabric.Services.Wcf 形式的 WcfCommunicationListener,但最后我们决定使用我们自己的 ICommunicationListener 实现,以便更好地控制服务主机。我们还使用 net.tcp 作为绑定而不是 http。我们以编程方式定义行为和端点,而不是使用 app.config。 我将分享我们的方法。希望对您有所帮助。
第一步,ICommunicationListener 实现:
public class ServiceHostCommunicationListener : ICommunicationListener
private string baseAddress;
public ServiceHost Host get; set;
public ServiceHostCommunicationListener(ServiceHost host, string baseAddress)
Host = host;
this.baseAddress = baseAddress;
public void Abort()
Host.Abort();
public async Task CloseAsync(CancellationToken cancellationToken)
try
await Task.Factory.FromAsync(Host.BeginClose(null, null), ar =>
Host.EndClose(ar);
);
catch (Exception)
Host.Abort();
public Task<string> OpenAsync(CancellationToken cancellationToken)
return Task.Factory.FromAsync(Host.BeginOpen(null, null), ar =>
Host.EndOpen(ar);
return baseAddress;
);
第二步,在我们的 Service Fabric 服务中的 CreateServiceInstanceListeners 中创建监听器的实例。这里是我创建服务主机实例、它的端点和行为的地方。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
yield return new ServiceInstanceListener(context =>
return CreateListener(context);
);
private ICommunicationListener CreateListener(StatelessServiceContext context)
Uri baseUri = new Uri($"net.tcp://configuration.Network.BaseAddress");
ServiceHost serviceHost = new ServiceHost(new SampleService(), baseUri);
InitServiceDebugBehavior(serviceHost);
if (configuration.Network.MetadataAddress != null)
AddMetadataEndpoint(baseUri, serviceHost);
InitServerCertificate(serviceHost);
AddServiceEndpoint(serviceHost);
return new ServiceHostCommunicationListener(serviceHost, baseUri.AbsoluteUri);
private void InitServiceDebugBehavior(ServiceHost host)
var serviceDebug = host.Description.Behaviors.Find<ServiceDebugBehavior>();
if (serviceDebug == null)
serviceDebug = new ServiceDebugBehavior();
host.Description.Behaviors.Add(serviceDebug);
serviceDebug.IncludeExceptionDetailInFaults = configuration.ServiceBehavior.ServerDebug.IncludeExceptionDetailInFaults;
private void AddMetadataEndpoint(Uri baseUri, ServiceHost serviceHost)
ServiceMetadataBehavior smb = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
smb = new ServiceMetadataBehavior();
serviceHost.Description.Behaviors.Add(smb);
serviceHost.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexTcpBinding(),
configuration.Network.MetadataAddress
);
private void InitServerCertificate(ServiceHost host)
var serverCertificateConfig = configuration.ServiceBehavior.ServerCertificate;
host.Credentials.ServiceCertificate.SetCertificate(
serverCertificateConfig.Store,
StoreName.My,
serverCertificateConfig.FindType,
serverCertificateConfig.FindValue
);
private void AddServiceEndpoint(ServiceHost serviceHost)
var binding = new NetTcpBinding(SecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
serviceHost.AddServiceEndpoint(typeof(SampleService), binding, configuration.Network.ServiceAddress);
这是配置文件,以防您有任何疑问。我们将其存储在 PackageRoot-Config 文件夹中。
"Network":
"BaseAddress": "localhost:1020/SampleService/",
"ServiceAddress": "service",
"MetadataAddress": "mex"
,
"ServiceBehavior":
"ServerCertificate":
"Store": "LocalMachine",
"FindType": "FindBySubjectDistinguishedName",
"FindValue": "CN=mycert.deploy.com"
,
"ServerDebug":
"IncludeExceptionDetailInFaults": true
【讨论】:
【参考方案2】:我唯一能想到的就是手动创建基于此示例的 Http 绑定:
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None)
SendTimeout = TimeSpan.MaxValue,
ReceiveTimeout = TimeSpan.MaxValue,
OpenTimeout = TimeSpan.FromSeconds(5),
CloseTimeout = TimeSpan.FromSeconds(5),
MaxReceivedMessageSize = 1024 * 1024
;
binding.MaxBufferSize = (int)binding.MaxReceivedMessageSize;
binding.MaxBufferPoolSize = Environment.ProcessorCount * binding.MaxReceivedMessageSize;
return binding;
使用该绑定,地址是服务结构资源管理器中的 http
【讨论】:
以上是关于天蓝色服务结构 wcf 端点地址 net.tcp 而不是 http的主要内容,如果未能解决你的问题,请参考以下文章
如何使用来自远程服务器的 net.tcp 端点 ping 或检查 WCF 服务的状态?