7

昨夜遭遇した問題が 2 つありますが、現在は解決していますが、なぜ私が行ったことでそれらの問題が解決したのかについては 100% 確信が持てません。運がなかった!

最初の問題

最初の問題は、2 つの別々のプログラムにある 2 つの一意の名前のパイプがあったことです。

  • net.pipe://localhost/superuniquepipe1
  • net.pipe://localhost/superuniquepipe2

ただし、起動する 2 番目のプログラムは、アドレスが既に使用されているため、ServiceHost を開くときに例外をスローします (AddressAlreadyInUseException だったと思います)。

これらの ServiceHosts をインスタンス化する方法次のとおりです。

Uri[] baseAddresses = new Uri[] { new Uri("net.pipe://localhost") };
this.host = new ServiceHost(this, baseAddresses);
this.host.AddServiceEndpoint(typeof(IHostType), new NetNamedPipeBinding(), "superuniquepipe1");
this.host.Open();

したがって、最初に localhost のベース アドレスを指定し、次にエンドポイントを追加するときに残りのアドレスを指定します。これを解決する方法は、次のようにコードを変更することでした。

this.host = new ServiceHost(this);
this.host.AddServiceEndpoint(typeof(IHostType), new NetNamedPipeBinding(), "net.pipe://localhost/superuniquepipe2");
this.host.Open();

これが機能した理由は、追加しようとしていたエンドポイントではなく、ベース アドレスのみをチェックしていたからだと言うのは正しいですか? また、2 番目のコード サンプルは、複数のプログラムが "localhost" でリッスンするための有効で安全な方法ですか?

2番目の問題:

上記の問題を解決するために、ベース アドレスを localhost から、「net.pipe://rawrwhyisntthisworkingsadface」などのさまざまな一意の文字列に変更しましたが、これを行うと、試行中のクライアントから InvalidCredentialException が表示されます。接続を確立する (以下のコードを参照)

名前付きパイプは文字通り何にでも名前を付けることができるという印象を受けましたが、誰かがこれに光を当てることができますか?

ChannelFactory<IHostType> factory = new ChannelFactory<IHostType>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://rawrwhyisntthisworkingsadface/superuniquepipe2"));
IHostType proxy = factory.CreateChannel();
proxy.CallSomeMethodAndGetAnException();

問題を解決したので、私の解決策が機能した理由を知りたいだけなので、どんな意見でも大歓迎ですが、私が解決した方法に欠陥があり、それを行うためのより良い方法を提案できる場合は、そうしてください:)

4

1 に答える 1

13

問題 1 について:

WCFNetNamedPipeBindingは、名前付き共有メモリ セクションを使用して、サービスを呼び出すことができるパイプの実際の名前をクライアントに公開します。パイプ名自体は GUID であり、サービス ホストが開かれるたびに新たに生成されます。これは、サービス URL に依存するサービスを公開するために使用される共有メモリ セクションの名前です。ベース アドレスが定義されている場合は、ベース アドレスを使用してこの名前が派生します。

これは、NetNamedPipe エンドポイントに特定のベース アドレスを使用する WCF サービス アプリケーションを一度に 1 つしか実行できないことを意味します。2 番目のものを開始しようとすると、WCF が公開場所に使用する名前 (ベース アドレスから派生) が別のアプリケーションによって既に使用されていることが判明するため、AddressAlreadyInUseException で失敗します。

ベース アドレスを指定せず、各サービスに一意の絶対 URL を指定すると、公開場所の名前は完全な絶対 URL から派生するようになり、アプリケーション間で名前の競合が発生しなくなります。これは、複数の WCF 名前付きパイプ サービスをリッスンさせるための完全に有効で安全な方法です。

問題 2 について:

サービス側では、サービス URL のホスト名部分に何でも使用できます。これはHostNameComparisonMode、NetNamePipeBinding で既定で適用される設定によるものです。これは、共有メモリの公開場所の名前を取得する WCF のアルゴリズムが、ホスト名の代わりにワイルドカード文字を使用するためです。構成済みのホスト名比較モードを実装するには、こちらを参照してください。

ただし、クライアント側では、サービス URL に制約があります。ホスト部分は、真に localhost に解決される必要があります (つまりlocalhost、正しい IP アドレスまたは正しいマシン名)。

于 2012-04-29T14:23:59.260 に答える