2

既知のエンドポイント上の1つのサービスが、相対アドレスである文字列を返す方法が必要です。その後、クライアントはこれらの相対アドレスを使用してエンドポイントに接続できます。明らかにこれはいくつかの点でRESTに似ていますが、この場合、IPCにNetNamedPipeBindingを使用してWindowsサービスを実行しているため、HTTPは必要ありません。

潜在的に多数の相対アドレスが存在するため、事前にエンドポイントを作成しないでください。クライアントが関心を持つのはそのうちの一部のみです。

すべての契約は事前に知られています。

AddressFilterModeで解決策を見つけようとしましたが、クライアントがそれに接続するように新しいBindingをプロビジョニングする方法がわかりませんでした。UriTemplateですが HTTPフレームワークを使用したくありません。.Net 3.5に制約されているため、 RoutingServiceを調べていません。

クライアントの擬似コードは次のようになります...

namespace Testing
{
    class RunTest
    {
        static void Test()
        {
            NetNamedPipeBinding namedpipe = new NetNamedPipeBinding();
            ChannelFactory<Contracts.IRoot> factoryRoot =
                new ChannelFactory<Contracts.IRoot>(
                namedpipe
                , new EndpointAddress("net.pipe://localhost/root");
            );
            Contracts.IRoot root = factoryRoot.CreateChannel();
            ICommunicationObject commsRoot = root as ICommunicationObject;
            commsRoot.Open();

            // Service examines address and creates Endpoint dynamically.
            string address = root.SomeFunctionWhichGetsARelativeAddress();

            // IBar service routes endpoint requests internally based on
            // "address" variable.
            ChannelFactory<Contracts.IBar> factoryBar = 
                new ChannelFactory<Contracts.IBar>(
                namedpipe
                , new EndpointAddress("net.pipe://localhost/root/IBar/" +
                                       address)
            );
            Contracts.IBar bar = factoryBar.CreateChannel();
            bar.DoSomething();
        }
    } // Ends class RunTest
} // Ends namespace Testing
4

2 に答える 2

0

AddressFilterMode.Prefixで十分な場合があります。使用される実際のエンドポイントは、 OperationContextを介してサービスメソッドで検査できます。現在IncomingMessageHeaders

ヘルパーコードはエンドポイントを解析し、そこから必要な内部処理を実行できます。うまくいけば、そのコードを単純化できるサーバー側の拡張性があります。

ホストの擬似コード:

namespace Services
{
    [System.ServiceModel.ServiceBehavior(AddressFilterMode =
         System.ServiceModel.AddressFilterMode.Prefix)]
    class BarService : Contracts.IBar
    {
        #region IBar Members

        public void DoSomething()
        {
            System.Uri endpoint = System.ServiceModel.OperationContext.Current.IncomingMessageHeaders.To;
            Console.WriteLine("DoSomething endpoint: {0}", endpoint);
        }
    } // Ends class BarService
} // Ends namespace Services
class RunHost
{
    static void HostIBar()
    {
        System.Uri uriBase = new System.Uri("net.pipe://localhost");
        System.ServiceModel.ServiceHost hostBar =
            new System.ServiceModel.ServiceHost(
            typeof(Services.BarService),
            uriBase);
        hostBar.AddServiceEndpoint(
              typeof(Contracts.IBar) // Type implementedContract
            , namedpipeBinding // System.ServiceModel.Channels.Binding binding
            , "root/IBar" //string address
        );
        hostBar.Open();

        Console.WriteLine("Press <ENTER> to stop...");
        Console.ReadLine();
    }
}

訂正:私は当初、これは別個のエンドポイントとしては扱われないと言っていましたが、そうします"net.pipe://localhost/root/IBar/1""net.pipe://localhost/root/IBar/2"それぞれが独自のWCFサービスインスタンスを作成して呼び出します。

追加の変更は、URLスタイルのクエリパラメータでデータをエンコードし、パスに埋め込まないことでした。例:HttpUtility.ParseQueryString"net.pipe://localhost/root/IBar?something=1&somethingelse=11""net.pipe://localhost/root/IBar?something=2&somethingelse=22"使用する

于 2012-06-12T12:35:30.880 に答える
0

メッセージフィルターはその方法です。「プレフィックス」を使用するか、カスタムを作成できます。

WCFの詳細なアドレス指定

記事のメッセージフィルターセクションから:

...メッセージフィルターを使用して、一致するエンドポイントが存在する場合はそれを判別します。使用するメッセージフィルターを選択することも、独自のメッセージフィルターを提供することもできます。この柔軟性により、Windows Communication Foundationを使用して従来のSOAP以外のものを実装するときに、従来のディスパッチモデルから脱却できます。たとえば、ここで説明する手法により、WindowsCommunicationFoundationメッセージング基盤にREST/POXスタイルのサービスを実装できます。

ちなみにいい質問ですね。私はこれを理解しようとして何かを学びました。

于 2012-06-13T16:16:50.140 に答える