2016-04-20 3 views
2

Der Versuch, eine Stateful zuverlässigen Service mit wcf in Service Gewebe zu gründen, habe ich diesen Beispielcode kopiert:azur Service Stoff wcf-Endpunkt-Adresse net.tcp statt http

protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners() 
{ 
    return new[] { new ServiceReplicaListener((context) => 
    new WcfCommunicationListener<IService1>(
     wcfServiceObject:this, 
     serviceContext:context,    
     endpointResourceName: "ServiceEndpoint", 
     listenerBinding: WcfUtility.CreateTcpListenerBinding() 
    ) 
)}; 

In ServiceManifest.xml ich erklärt haben, der Endpunkt:

<Resources> 
    <Endpoints> 
     <Endpoint Name="ServiceEndpoint" Protocol="http" Port="8100" /> 
     <Endpoint Name="ReplicatorEndpoint" /> 
    </Endpoints> 
    </Resources> 

Aber wenn ich auf lokale Cluster bereitstellen, und am Knoten schauen, wo der Dienst in Service Fabric Explorer ausgeführt wird, hat der Endpunkt diese Adresse:

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

Wie bekomme ich eine http-Adresse?

+0

Der Punkt ist, dass Ihre listenerBinding-Eigenschaft mit WcfUtility.CreateTcpListenerBinding() zugewiesen ist. Ich nehme an, es ist der einzig mögliche Weg, denn es gibt keine andere Methode in WcfUtility, aber sieh dir diesen Link an, vielleicht hilft er dir ein bisschen: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-services-communication-wcf/ –

+0

Vielen Dank für Ihre Antwort, ich vermutete das Problem war mit dem Zuhörer binden. Auf der Seite, auf die Sie verweisen, habe ich meinen Code von :-). Ich konnte keine andere Dokumentation über die Verwendung von Service-Fabric mit WCF finden. – Kayak58

Antwort

0

Das einzige, was ich denken kann manuell die Http in diesem Beispiel auf Basis schaffen Bindung:

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; 

Damit die Adresse Bindung http in Service Stoff Explorer

0

Auf meinem Team, wir haben habe in diesen Tagen mit WCF in Service Fabric gearbeitet. Zuerst haben wir versucht, WcfCommunicationListener von Microsoft.ServiceFabric.Services.Wcf zu verwenden, aber schließlich entscheiden wir uns, unsere eigene Implementierung von ICommunicationListener zu verwenden, um eine bessere Kontrolle über den Service-Host zu haben. Wir verwenden auch net.tcp als bindend anstelle von http. Wir haben Verhalten und Endpunkte programmatisch definiert, nicht mit app.config. Ich werde unseren Ansatz teilen. Hoffe, das kann dir helfen.

erster Schritt die ICommunicationListener Umsetzung:

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; 
     }); 
    } 
} 

zweiter Schritt erstellen Instanz des Zuhörers innerhalb CreateServiceInstanceListeners in unserem Service-Fabric-Service. Hier habe ich eine Service-Host-Instanz, ihre Endpunkte und Verhaltensweisen erstellt.

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); 
    } 

Hier ist die Konfigurationsdatei, falls Sie Zweifel darüber haben. Wir speichern es im PackageRoot-Config-Ordner.

{ 
    "Network": { 
     "BaseAddress": "localhost:1020/SampleService/", 
     "ServiceAddress": "service", 
     "MetadataAddress": "mex" 
     }, 
    "ServiceBehavior": { 
     "ServerCertificate": { 
     "Store": "LocalMachine", 
     "FindType": "FindBySubjectDistinguishedName", 
     "FindValue": "CN=mycert.deploy.com" 
     }, 
    "ServerDebug": { 
     "IncludeExceptionDetailInFaults": true 
     } 
    } 
    }