2016-04-20 123 views
2

試圖建立與服務織物WCF有狀態的可靠的服務,我抄這個示例代碼:蔚藍服務織物WCF端點地址的net.tcp而非http

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> 

但是當我部署到本地集羣,並期待在這裏的服務是在服務織物Explorer中運行的節點,端點有這個地址:

net.tcp://localhost:8100/455d1c74-7734-449b-a567-47b749b3b822/88af6851-0285-4989-b0aa-c0cbe8c2d06a-131056235989980581 

如何獲取http地址?

+0

問題是您的listenerBinding屬性被分配了WcfUtility.CreateTcpListenerBinding()。我認爲這是目前唯一可行的方法,因爲WcfUtility中沒有其他方法,但請查看此鏈接,也許它會對您有所幫助:https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication-wcf/ –

+0

感謝您的回覆,我懷疑問題是與監聽器綁定。您提到的頁面是我從哪裏得到我的代碼的地方:-)。我一直無法找到任何有關使用wcf服務結構的其他文檔。 – Kayak58

回答

0

我能想到的是手動創建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服務織物探險

0

在我的球隊,我們有這些天一直在服務結構中使用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 
     } 
    } 
    }