2016-04-20 114 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 
     } 
    } 
    }