WCF名前付きパイプの最小限の例


90

WCF名前付きパイプの最小限の例を探しています(名前付きパイプを介して通信できるサーバーとクライアントの2つの最小限のアプリケーションが必要です)。

Microsoftには、HTTPを介してWCFを説明する華麗な記事Getting Started Tutorialがあり、WCFと名前付きパイプについて類似したものを探しています。

私はインターネットでいくつかの投稿を見つけましたが、それらは少し「高度」です。最低限必要な機能だけが必要なので、コードを追加してアプリケーションを動作させることができます。

名前付きパイプを使用するように置き換えるにはどうすればよいですか?

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

名前付きパイプを使用するように置き換えるにはどうすればよいですか?

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

名前付きパイプを使用するクライアントを生成するにはどうすればよいですか?


1
stackoverflow.com/questions/184878/…を見たことがありますか?
クリストフ

回答:


80

私はこの素晴らしい小さなチュートリアルを見つけました。 リンク切れキャッシュバージョン

マイクロソフトのチュートリアルも良かったですが、必要なのはパイプだけです。

ご覧のとおり、構成ファイルなどの面倒なものは必要ありません。

ちなみに、彼はHTTPとパイプの両方を使用しています。HTTPに関連するすべてのコード行を削除するだけで、純粋なパイプの例が得られます。


2
ありがとう!また、ハードコードされた構成ではなく、構成にweb.configを使用するサービスを構築する場合は、次のMicrosoftの例を参照してください。msdn.microsoft.com
us

3
リンクが機能しません。チュートリアルは他にありますか?
user1069816 2015

「パイプが終了した」理由を理解するためにしばらく時間を費やしただけです。これが私の解決策です。うまくいけば役に立ちます:stackoverflow.com/a/49075797/385273
Ben

62

これを試して。

こちらがサービスパーツです。

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

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

ここにプロキシがあります

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

そしてこれがサービスホスティングの部分です。

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

これはうまくいくかもしれませんが、クライアントとサーバーのapp.configファイルを編集するほど柔軟ではありません...
Alan S

9
多くの場合、app.configファイルを介してアプリケーションの詳細を公開することは望ましくないためです。
Frank Hileman、2014

14
これは素晴らしい例ですが、net.pipe:// localhost /だけのベースアドレスは使用しないでください。そうすると、マシンにnet.pipe:// localhost /も使用する他のプログラムがある場合、ServiceHostを開くと例外がスローされます。代わりに、net.pipe:// localhost / MyAppNameThatNobodyElseWillUseのようなユニークなものを使用してください。これが他の誰かの時間とフラストレーションを節約するのに役立つことを願っています!
Doug Clutter

このソリューションはうまく機能します。特に、configにサービス参照を含める必要がない内部エンドポイントの場合。コントラクト-単にインターフェース定義-を独自のアセンブリとおそらくconfigのアドレスに保持します。バインディングが変更される可能性はそれほど高くありません。
Rob Von Nesselrode 2016

2
/helloserviceプロキシのエンドポイントアドレスの末尾に追加する必要がありました。
モルメジル

14

私の非常に単純化されたEchoの例を確認してください。これは基本的なHTTP通信を使用するように設計されていますが、app.configを編集することで名前付きパイプを使用するように簡単に変更できます。ますが、クライアントとサーバーのファイルをます。次の変更を行います。

編集サーバのapp.configをのファイル、削除またはコメントアウトHTTP BASEADDRESSエントリを、新たな追加BASEADDRESSの(と呼ばれる名前付きパイプのエントリnet.pipeを)。また、通信プロトコルにHTTPを使用する予定がない場合は、serviceMetadataおよびserviceDebugがコメント化されているか削除されていることを確認してください。

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

編集クライアントのapp.configをのようにファイルbasicHttpBindingはどちらかコメントアウトまたは削除されnetNamedPipeBindingのエントリが追加されます。パイプを使用するには、エンドポイントエントリも変更する必要があります

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

上記の例は名前付きパイプでのみ実行されますが、サービスを実行するために複数のプロトコルを使用することを妨げるものは何もありません。AFAIK、名前付きパイプとHTTP(およびその他のプロトコル)の両方を使用してサーバーでサービスを実行できるようにする必要があります。

また、クライアントのapp.configファイルのバインディングは非常に単純化されています。baseAddressを指定するだけでなく、調整可能な多くの異なるパラメーターがあります...


5
リンクは今死んでいる。
Chris Weber

2

この簡単な例は、インターネット上のさまざまな検索結果から作成しました。

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

上記のURIを使用して、クライアントの参照をWebサービスに追加できます。


-2

私はこのサイトが本当に役立つとわかり、サンプルプロジェクトは調整せずに実行できます。 https //dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html

Windowsの機能で名前付きパイプのサポートを有効にすることを忘れないでください。この記事の上部の回答には、その効果を示す良いスクリーンショットがいくつかあります。 にあります。App.Configを使用したWindowsサービスのWCF名前付きパイプ

承認されたソリューションで参照されているプロジェクトが、そのままPCで実行されません。app.configでいくつかの修正を試みましたが、それでも次の例外が発生します。

System.InvalidOperationException: 'Service' WpfWcfNamedPipeBinding.NamedPipeBindingService 'には、アプリケーション(インフラストラクチャでない)エンドポイントがありません。これは、アプリケーションの構成ファイルが見つからなかったか、構成ファイルでサービス名と一致するサービス要素が見つからなかったか、サービス要素でエンドポイントが定義されていなかったことが原因である可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.