Contoh pipa minimal yang diberi nama WCF

90

Saya mencari contoh minimal WCF Named Pipes (Saya mengharapkan dua aplikasi minimal, server dan klien, yang dapat berkomunikasi melalui pipa bernama.)

Microsoft memiliki artikel cemerlang tentang Tutorial Memulai yang menjelaskan WCF melalui HTTP, dan saya mencari sesuatu yang serupa tentang WCF dan pipa bernama.

Saya telah menemukan beberapa posting di Internet, tetapi mereka sedikit "maju". Saya membutuhkan sesuatu yang minimal, hanya fungsionalitas wajib, jadi saya dapat menambahkan kode saya dan menjalankan aplikasi.

Bagaimana cara menggantinya dengan menggunakan pipa bernama?

<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>

Bagaimana cara menggantinya dengan menggunakan pipa bernama?

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

Bagaimana cara membuat klien menggunakan pipa bernama?

Oleg Vazhnev
sumber
1
pernahkah Anda melihat stackoverflow.com/questions/184878/… ?
Christoph

Jawaban:

80

Saya baru saja menemukan tutorial kecil yang luar biasa ini . tautan rusak ( versi cache )

Saya juga mengikuti tutorial Microsoft yang bagus, tapi saya hanya membutuhkan pipa juga.

Seperti yang Anda lihat, Anda tidak memerlukan file konfigurasi dan semua hal yang berantakan itu.

Ngomong-ngomong, dia menggunakan HTTP dan pipa. Hapus saja semua baris kode yang terkait dengan HTTP, dan Anda akan mendapatkan contoh pipa murni.

Juan
sumber
2
Terima kasih! Selain itu, ketika mencoba membangun layanan yang menggunakan web.config untuk konfigurasinya, bukan konfigurasi hardcode, lihat contoh microsoft ini: msdn.microsoft.com/en-us/library/ms752253.aspx
Nullius
3
Tautan tidak berfungsi, apakah tutorialnya ada di tempat lain?
pengguna1069816
Hanya menghabiskan beberapa saat mencoba mencari tahu mengapa "pipa telah diakhiri". Inilah pemecahan saya untuk yang satu itu, semoga membantu: stackoverflow.com/a/49075797/385273
Ben
62

Coba ini.

Ini bagian layanan.

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

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

Ini Proksi

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

Dan inilah bagian layanan 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);
    }
Anuraj
sumber
Ini mungkin berhasil, tetapi tidak sefleksibel hanya mengedit file app.config untuk klien dan server ...
Alan S
9
Bagus, karena mengekspos detail aplikasi melalui file app.config seringkali tidak diinginkan.
Frank Hileman
14
Ini adalah contoh yang bagus, namun, jangan pernah menggunakan alamat dasar hanya net.pipe: // localhost /. Jika Anda melakukannya dan mesin memiliki program lain yang juga menggunakan net.pipe: // localhost / maka ServiceHost akan mengeluarkan pengecualian saat Anda membukanya. Sebagai gantinya, gunakan sesuatu yang unik seperti net.pipe: // localhost / MyAppNameThatNobodyElseWillUse. Semoga ini membantu menghemat waktu dan frustrasi orang lain!
Doug Clutter
Solusi ini bekerja dengan baik. Khususnya untuk titik akhir internal yang tidak memerlukan referensi layanan dalam konfigurasi. Simpan saja kontrak - hanya definisi antarmuka - di rakitan mereka sendiri dan mungkin alamat di config. Ini tidak terlalu mungkin bahwa pengikatan akan berubah.
Rob Von Nesselrode
2
Saya perlu menambahkan /helloserviceke ujung alamat titik akhir di proxy.
Mormegil
14

Lihat contoh Echo saya yang sangat disederhanakan : Ini dirancang untuk menggunakan komunikasi HTTP dasar, tetapi dapat dengan mudah dimodifikasi untuk menggunakan pipa bernama dengan mengedit file app.config untuk klien dan server. Lakukan perubahan berikut:

Edit file app.config server , hapus atau komentari entri http baseAddress dan tambahkan entri baseAddress baru untuk pipa bernama (disebut net.pipe ). Selain itu, jika Anda tidak bermaksud menggunakan HTTP untuk protokol komunikasi, pastikan serviceMetadata dan serviceDebug diberi komentar atau dihapus:

<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>

Edit file app.config klien sehingga basicHttpBinding bisa dikomentari atau dihapus dan entri netNamedPipeBinding ditambahkan. Anda juga perlu mengubah entri titik akhir untuk menggunakan pipa:

<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>

Contoh di atas hanya akan berjalan dengan pipa bernama, tetapi tidak ada yang menghentikan Anda dari menggunakan beberapa protokol untuk menjalankan layanan Anda. AFAIK, Anda harus dapat membuat server menjalankan layanan menggunakan pipa bernama dan HTTP (serta protokol lain).

Juga, pengikatan di klien file app.configsangat disederhanakan. Ada banyak parameter berbeda yang dapat Anda sesuaikan, selain dari hanya menentukan baseAddress ...

Alan S
sumber
5
Tautan sekarang sudah mati.
Chris Weber
2

Contoh sederhana ini saya buat dari berbagai hasil pencarian di 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;
}

Menggunakan URI di atas, saya dapat menambahkan referensi di klien saya ke layanan web.

Rahbek
sumber
-2

Saya menemukan situs ini sangat membantu, dan proyek contoh berjalan tanpa penyesuaian apa pun: https://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html

Jangan lupa untuk mengaktifkan dukungan Pipa Bernama di Fitur Windows. Artikel ini memiliki beberapa tangkapan layar yang bagus untuk efek itu di jawaban teratas: WCF Named Pipe di Windows Service menggunakan App.Config

Proyek yang direferensikan dalam solusi yang diterima tidak berjalan sebagaimana adanya di PC saya. Saya mencoba beberapa perbaikan di app.config tetapi masih mendapatkan pengecualian berikut:

System.InvalidOperationException: 'Service' WpfWcfNamedPipeBinding.NamedPipeBindingService 'tidak memiliki titik akhir aplikasi (non-infrastruktur). Ini mungkin karena tidak ada file konfigurasi yang ditemukan untuk aplikasi Anda, atau karena tidak ada elemen layanan yang cocok dengan nama layanan yang dapat ditemukan di file konfigurasi, atau karena tidak ada titik akhir yang ditentukan dalam elemen layanan. '

VoteCoffee
sumber