WCF adlı boru minimum örneği


90

Minimum WCF Adlandırılmış Borular örneği arıyorum (Adlandırılmış bir kanal aracılığıyla iletişim kurabilen iki minimum uygulama, sunucu ve istemci bekliyorum.)

Microsoft, HTTP aracılığıyla WCF'yi açıklayan Başlarken Eğitimi makalesine sahiptir ve WCF ve adlandırılmış kanallar hakkında benzer bir şey arıyorum.

İnternette birkaç gönderi buldum, ancak bunlar biraz "gelişmiş". Minimum bir şeye ihtiyacım var, yalnızca zorunlu işlevsellik, böylece kodumu ekleyebilir ve uygulamayı çalıştırabilirim.

Bunu adlandırılmış bir kanal kullanmak için nasıl değiştiririm?

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

Bunu adlandırılmış bir kanal kullanmak için nasıl değiştiririm?

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

Adlandırılmış bir kanal kullanmak için nasıl bir istemci oluşturabilirim?


Yanıtlar:


80

Bu harika küçük öğreticiyi buldum . bozuk bağlantı ( Önbelleğe alınmış sürüm )

Ayrıca Microsoft'un güzel eğitimini de takip ettim, ancak sadece borulara ihtiyacım vardı.

Gördüğünüz gibi, yapılandırma dosyalarına ve tüm bu dağınık şeylere ihtiyacınız yok.

Bu arada, hem HTTP hem de boru kullanıyor. Sadece HTTP ile ilgili tüm kod satırlarını kaldırırsanız saf bir boru örneği alırsınız.


2
Teşekkürler! Ayrıca, yapılandırması için sabit kodlanmış yapılandırma yerine web.config kullanan bir hizmet oluşturmaya çalışırken, şu Microsoft örneğine bakın
Nullius

3
Bağlantı çalışmıyor, eğitim başka bir yerde mi?
user1069816

Bir süre "borunun neden bittiğini" anlamaya çalıştım. İşte bu
Ben

62

Bunu dene.

İşte servis kısmı.

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

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

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

Ve işte servis barındırma kısmı.

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

Bu işe yarayabilir, ancak istemci ve sunucu için sadece app.config dosyalarını düzenlemek kadar esnek değildir ...
Alan S

9
Güzel, çünkü uygulama ayrıntılarının app.config dosyaları aracılığıyla gösterilmesi genellikle istenmiyor.
Frank Hileman

14
Bu harika bir örnektir, ancak asla sadece net.pipe: // localhost / temel adresini kullanmayın. Varsa ve makinede net.pipe: // localhost / kullanan başka bir program varsa, ServiceHost onu açtığınızda bir istisna atacaktır. Bunun yerine, net.pipe: // localhost / MyAppNameThatNobodyElseWillUse gibi benzersiz bir şey kullanın. Umarım bu, bir başkasını biraz zaman ve hayal kırıklığından kurtarmaya yardımcı olur!
Doug Clutter

Bu çözüm iyi çalışıyor. Özellikle konfigürasyonda servis referansına sahip olmanın gerekli olmadığı dahili uç noktalar için. Sadece sözleşmeleri - sadece arayüz tanımlarını - kendi derlemelerinde ve belki de adresi yapılandırmada saklayın. Bağlantının değişmesi pek olası değil.
Rob Von Nesselrode

2
/helloserviceProxy'deki uç nokta adresinin sonuna eklemem gerekiyordu .
Mormegil

14

Göz atın benim Oldukça basitleştirilmiş Echo örneğime bir : Temel HTTP iletişimini kullanmak için tasarlanmıştır, ancak istemci ve sunucu için app.config dosyalarını düzenleyerek adlandırılmış kanalları kullanmak için kolayca değiştirilebilir . Aşağıdaki değişiklikleri yapın:

Düzenleme sunucunun app.config dosyası çıkarmadan veya http dışında yorum BaseAddress girişi ve yeni bir ekleme BaseAddress adlandırılmış kanal (denilen girdisini net.pipe ). Ayrıca, bir iletişim protokolü için HTTP kullanmayı düşünmüyorsanız, serviceMetadata ve serviceDebug öğelerinin yorumlandığından veya silindiğinden emin olun :

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

İstemcinin app.config dosyasını, basicHttpBinding'e açıklama eklenecek veya silinecek ve netNamedPipeBinding girişi eklenecek şekilde düzenleyin . Ayrıca değiştirmeniz gerekecektir.boruyu kullanmak için uç nokta girişini:

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

Yukarıdaki örnek yalnızca adlandırılmış kanallarla çalışacaktır, ancak hizmetinizi çalıştırmak için birden çok protokol kullanmanıza engel olan hiçbir şey yoktur. AFAIK, bir sunucunun hem adlandırılmış yöneltmeleri hem de HTTP'yi (ve diğer protokolleri) kullanarak bir hizmeti çalıştırmasını sağlayabilmelisiniz.

Ayrıca, istemcinin app.config dosyasındaki bağlama oldukça basitleştirilmiştir. Sadece baseAddress'i belirtmenin yanı sıra, ayarlayabileceğiniz birçok farklı parametre vardır ...


5
Bağlantılar artık öldü.
Chris Weber

2

Bu basit örneği internetteki farklı arama sonuçlarından oluşturdum.

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

Yukarıdaki URI'yi kullanarak istemcimde web hizmetine bir referans ekleyebilirim.


-2

Bu siteyi gerçekten yararlı buldum ve örnek proje herhangi bir değişiklik yapılmadan çalışıyor: https://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html

Windows Özelliklerinde İsimli Kanal desteğini etkinleştirmeyi unutmayın. Bu makale, en iyi yanıtta bu etkiye yönelik bazı iyi ekran görüntülerine sahiptir: App.Config kullanarak Windows Hizmetinde WCF Adlandırılmış Kanal

Kabul edilen çözümde referans verilen proje bilgisayarımda olduğu gibi çalışmıyor. App.config dosyasında birkaç düzeltmeyi denedim, ancak yine de aşağıdaki istisnayı alıyorum:

System.InvalidOperationException: 'Hizmet' WpfWcfNamedPipeBinding.NamedPipeBindingService 'sıfır uygulama (altyapı dışı) uç noktalarına sahip. Bunun nedeni, uygulamanız için hiçbir yapılandırma dosyasının bulunmaması veya yapılandırma dosyasında hizmet adıyla eşleşen hiçbir hizmet öğesinin bulunamaması veya hizmet öğesinde hiçbir uç noktanın tanımlanmamış olması olabilir. '

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.