在我的球隊,我們有這些天一直在服務結構中使用wcf。首先,我們嘗試使用WcfCommunicationListener格式Microsoft.ServiceFabric.Services.Wcf,但最終我們決定使用自己的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中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
}
}
}
問題是您的listenerBinding屬性被分配了WcfUtility.CreateTcpListenerBinding()。我認爲這是目前唯一可行的方法,因爲WcfUtility中沒有其他方法,但請查看此鏈接,也許它會對您有所幫助:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication-wcf/ –
感謝您的回覆,我懷疑問題是與監聽器綁定。您提到的頁面是我從哪裏得到我的代碼的地方:-)。我一直無法找到任何有關使用wcf服務結構的其他文檔。 – Kayak58