2011-09-08 6 views
86

sto cercando minimo esempio di WCF named pipe (mi aspetto due minimo di applicazioni, server e client, in grado di comunicare tramite una named pipe.)WCF named pipe minimo esempio

Microsoft ha l'articolo Briliant Getting Started Tutorial che descrive WCF via HTTP e sto cercando qualcosa di simile a WCF e named pipe.

Ho trovato diversi post in Internet, ma sono un po '"avanzati". Ho bisogno di qualcosa di minimo, solo funzionalità obbligatoria, quindi posso aggiungere il mio codice e far funzionare l'applicazione.

Come sostituirlo per utilizzare una pipe denominata?

<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService" 
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator" 
    contract="ICalculator" name="WSHttpBinding_ICalculator"> 
    <identity> 
     <userPrincipalName value="OlegPc\Oleg" /> 
    </identity> 
</endpoint> 

Come si sostituisce quella di utilizzare una named pipe?

// Step 1 of the address configuration procedure: Create a URI to serve as the base address. 
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service"); 

// Step 2 of the hosting procedure: Create ServiceHost 
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress); 

try 
{ 
    // Step 3 of the hosting procedure: Add a service endpoint. 
    selfHost.AddServiceEndpoint(
     typeof(ICalculator), 
     new WSHttpBinding(), 
     "CalculatorService"); 

    // Step 4 of the hosting procedure: Enable metadata exchange. 
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); 
    smb.HttpGetEnabled = true; 
    selfHost.Description.Behaviors.Add(smb); 

    // Step 5 of the hosting procedure: Start (and then stop) the service. 
    selfHost.Open(); 
    Console.WriteLine("The service is ready."); 
    Console.WriteLine("Press <ENTER> to terminate service."); 
    Console.WriteLine(); 
    Console.ReadLine(); 

    // Close the ServiceHostBase to shutdown the service. 
    selfHost.Close(); 
} 
catch (CommunicationException ce) 
{ 
    Console.WriteLine("An exception occurred: {0}", ce.Message); 
    selfHost.Abort(); 
} 

Come si genera un client per utilizzare una named pipe?

+1

hai guardato http://stackoverflow.com/questions/184878/expose-a-wcf-service-through-a-named-pipes-binding? –

+1

ancora non capisco ... – javapowered

risposta

78

Ho appena trovato this excellent little tutorial.link interrotto (Cached version)

Ho anche seguito il tutorial di Microsoft che è bello, ma ho solo bisogno di tubi pure.

Come puoi vedere, non hai bisogno di file di configurazione e di tutto quel materiale confuso.

A proposito, utilizza sia HTTP che pipe. Basta rimuovere tutte le code line relative a HTTP e otterrai un esempio di pipe puro.

+2

Grazie! Inoltre, quando si tenta di creare un servizio che utilizza il web.config per la sua configurazione anziché la configurazione hardcoded, consultare questo esempio di microsoft: http://msdn.microsoft.com/en-us/library/ms752253.aspx – Nullius

+3

Il collegamento non funziona funziona, il tutorial è altrove? – user1069816

+0

Quel collegamento era esattamente ciò di cui avevo bisogno, grazie. – Patrick

52

Prova questo.

Ecco la parte di servizio.

[ServiceContract] 
public interface IService 
{ 
    [OperationContract] 
    void HelloWorld(); 
} 

public class Service : IService 
{ 
    public void HelloWorld() 
    { 
     //Hello World 
    } 
} 

Qui è il proxy

public class ServiceProxy : ClientBase<IService> 
{ 
    public ServiceProxy() 
     : base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)), 
      new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyAppNameThatNobodyElseWillUse/helloservice"))) 
    { 

    } 
    public void InvokeHelloWorld() 
    { 
     Channel.HelloWorld(); 
    } 
} 

E qui è la parte del servizio di hosting.

var serviceHost = new ServiceHost 
     (typeof(Service), new Uri[] { new Uri("net.pipe://localhost/MyAppNameThatNobodyElseWillUse") }); 
    serviceHost.AddServiceEndpoint(typeof(IService), new NetNamedPipeBinding(), "helloservice"); 
    serviceHost.Open(); 

    Console.WriteLine("Service started. Available in following endpoints"); 
    foreach (var serviceEndpoint in serviceHost.Description.Endpoints) 
    { 
     Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri); 
    } 
+0

grazie, darò un'occhiata ... – javapowered

+0

Questo potrebbe funzionare, ma non è così flessibile come basta modificare l'app File .config per client e server ... –

+7

Bello, dal momento che esporre i dettagli dell'applicazione tramite i file app.config spesso non è desiderato. –

11

controllare il mio highly simplified Echo example: È stato progettato per utilizzare la comunicazione HTTP di base, ma può essere facilmente modificato per utilizzare named pipe modificando app.config file per il client e il server. Apportare le seguenti modifiche:

Modificare il file del server app.config, rimozione o commentando la http BaseAddress ingresso e l'aggiunta di una nuova BaseAddress voce per il named pipe (chiamato net.pipe).Inoltre, se non si intende usare HTTP per un protocollo di comunicazione, assicurarsi che il serviceMetadata e serviceDebug è o commentato fuori o cancellati:

<configuration> 
    <system.serviceModel> 
     <services> 
      <service name="com.aschneider.examples.wcf.services.EchoService"> 
       <host> 
        <baseAddresses> 
         <add baseAddress="net.pipe://localhost/EchoService"/> 
        </baseAddresses> 
       </host> 
      </service> 
     </services> 
     <behaviors> 
      <serviceBehaviors></serviceBehaviors> 
     </behaviors> 
    </system.serviceModel> 
</configuration> 

Modificare il file del client app.config così che la basicHttpBinding è o commentate fuori o cancellati e viene aggiunto un netNamedPipeBinding ingresso. Sarà inoltre necessario modificare la voce endpoint di utilizzare il tubo:

<configuration> 
    <system.serviceModel> 
     <bindings> 
      <netNamedPipeBinding> 
       <binding name="NetNamedPipeBinding_IEchoService"/> 
      </netNamedPipeBinding> 
     </bindings> 
     <client> 
      <endpoint address    = "net.pipe://localhost/EchoService" 
         binding    = "netNamedPipeBinding" 
         bindingConfiguration = "NetNamedPipeBinding_IEchoService" 
         contract    = "EchoServiceReference.IEchoService" 
         name     = "NetNamedPipeBinding_IEchoService"/> 
     </client> 
    </system.serviceModel> 
</configuration> 

L'esempio precedente verrà eseguito solo con named pipe, ma nulla vi impedisce di utilizzare protocolli multipli per eseguire il servizio. AFAIK, dovresti essere in grado di avere un server che esegue un servizio usando sia named pipes che HTTP (così come altri protocolli).

Inoltre, il legame nel file di app.config del cliente è molto semplificata. Ci sono molti parametri che si possono regolare, a parte solo specificando il BaseAddress ...

+3

I collegamenti ora sono morti. –

0

Ho creato questo semplice esempio dai risultati di ricerca diversi su Internet.

public static ServiceHost CreateServiceHost(Type serviceInterface, Type implementation) 
{ 
    //Create base address 
    string baseAddress = "net.pipe://localhost/MyService"; 

    ServiceHost serviceHost = new ServiceHost(implementation, new Uri(baseAddress)); 

    //Net named pipe 
    NetNamedPipeBinding binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 2147483647 }; 
    serviceHost.AddServiceEndpoint(serviceInterface, binding, baseAddress); 

    //MEX - Meta data exchange 
    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 
    serviceHost.Description.Behaviors.Add(behavior); 
    serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), baseAddress + "/mex/"); 

    return serviceHost; 
} 

Utilizzando quanto sopra URI posso aggiungere un riferimento nel mio client al servizio Web.