0

私は何年もの間、プロのプログラマーとして、stackoverflow.com をリソースとして使用してきました。Google で何かを検索すると、10 回中 8 回は、ここで質問と回答が示されます。必要な情報がすぐに見つかるとわかっているので、そのときはいつもほっとしています。

私は、WCF テクノロジを使用したルーティング サービスの設定に関する単純な問題 (と私が考えるもの) を理解しようとして、頭を悩ませてきました。ここで同様のタイトルの質問を閲覧し、これを理解しようとして非常に多くのリソース (このテーマに関する実際の本と Web サイトの両方) を参照しましたが、役に立ちませんでした。

一言で言えば、次のレイアウトでシステムをセットアップしたいと考えています。

{client}<-basicHTTP->{portal/router}<-fullWCF-WS*->{end-point-services1..n}

client : ポータルへのサービス参照を取得し、エンドポイント サービスで関数を呼び出すことができます
portal/router : クライアントから要求を取得し、マルチキャスト セットアップでエンドポイント サービスに送信します
end-point-services1..n :クライアントからリクエストを取得し、ポータルを介してルーティングし、リクエストを処理して検索し、応答するか、後でチェックするためにデータベースにデータを記録します

私は、100% ルーティング サービスを稼働させることができます。私が従うことができた最も成功したモデルは、「WCF4 の新機能: 演習 8 と 9、コンテンツ ブリッジングとルーティング」(msdn.microsoft.com/en-us/gg465212) および「Hello World with the Routing Service" (msdn.microsoft.com/en-us/library/dd795218.aspx) しかし、私が調べたすべての情報源 (以下にリスト) から少しずつ使用しました。

基本的に、私をイライラさせているのは、クライアント (サード パーティ) が Web サービス参照をポータル サービスに追加するだけで (または、最悪の場合は svcutil.exe メソッドを使用して)、完了できるようにしたいということです彼らの側でセットアップを行います。その参照により、すべてのシナリオで呼び出したいすべての関数/メソッドへの参照が得られます。私が調べたモデルでは、これを行うには、実際のサービスへの参照とルーターへの参照の 2 つの参照が必要であり、クライアントがセットアップで特にルーターを呼び出すように強制します。この特定のセットアップを機能させるための他の試みはどれもうまくいきませんでした。

これについてあなたの助けをいただければ幸いです。


これは、私が望むこと をほぼ実行している私の作業モデルの簡略化されたバージョンです。


(すべてのサービスが IIS でホストされていることに注意してください)

ポータル サービス (および IIS ホスト)

Portal.svc:
<%@ ServiceHost Service="System.ServiceModel.Routing.RoutingService, System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
Web.config:

<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      ...  
    </bindings>
    <client>
      <endpoint address="http://searcher1/Searcher.svc/general" binding="basicHttpBinding" contract="*" name="regularSearchServiceEndpoint" />
      <endpoint address="http://searcher2/Searcher.svc/general" binding="basicHttpBinding" contract="*" name="regularSearchServiceEndpoint2" />
    </client>
    <behaviors>
      ...
    </behaviors>
    <routing>
      <filters>
        <filter name="MatchAllFilter" filterType="MatchAll" />
      </filters>
      <filterTables>
        <filterTable name="filterTable1">
          <add filterName="MatchAllFilter" endpointName="regularSearchServiceEndpoint" backupList="backupList1" priority="0"/>
        </filterTable>
      </filterTables>
      <backupLists>
        <backupList name="backupList1">
          <add endpointName="regularSearchServiceEndpoint2"/>
        </backupList>
      </backupLists>
    </routing>
    <services>
      <service behaviorConfiguration="routingConfiguration" name="System.ServiceModel.Routing.RoutingService">
        <endpoint address="general" binding="basicHttpBinding" name="routerEndpoint1" contract="System.ServiceModel.Routing.IRequestReplyRouter" />
      </service>
    </services>
  </system.serviceModel>
</configuration>


検索サービス

ISearch.cs:

namespace SearchService
{
  [ServiceContract]
  public interface ISearch
  {
    [OperationContract]
    string Ping();
    [OperationContract]
    string searchByInput(string input);
  }
}

App.config:

<configuration>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        ...
      </basicHttpBinding>
      <customBinding>
        ...
      </customBinding>
    </bindings>
    <client>
      ...
    </client>
    <services>
      <service name="SearchService.Search">
        <endpoint address="general" binding="basicHttpBinding" contract="SearchService.ISearch" name="SearchService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/SearchService/Service1/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>


検索サービス ホスト

Search.svc:
<%@ ServiceHost Service="SearchService.Search" %>
Web.config:

<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      <basicHttpBinding>
        <!--copied over from SearchService.App.config-->
      </basicHttpBinding>
      <customBinding>
        <!--copied over from SearchService.App.config-->
      </customBinding>
    </bindings>
    <client>
      <!--copied over from SearchService.App.config-->
    </client>
    <services>
      ...
    </services>
    <behaviors>
      ...
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>


クライアント (すべてがうまくいかない場合)

私がやりたいことを実行できる唯一の方法は、サーチャー サービス (「remotehost」という名前) への Web サービス参照を追加し、ルーターの app.config ファイルにクライアント エンドポイントを手動で追加することです。クライアントコードがそれを使用するように強制し、サーチャーへの直接リンクの代わりに

Main.cs:

namespace Client  
{  
  public partial class Main : Form  
  {  
    remotehost.SearchClient proxy;  
    public Main()  
    {  
      InitializeComponent();  
      proxy = new remotehost.SearchClient("RouterService");//("BasicHttpBinding_ISearch")  
    }  
    private void button1_Click(object sender,EventArgs e)  
    {  
      string response = string.Empty;
      //uses method exposed by the SearchService service
      response = proxy.Ping();
      MessageBox.Show("Response from remote service:\n" + response
        "Ping Response",
        MessageBoxButtons.OK,
        MessageBoxIcon.Information);
    }
  }
}

App.config:

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        ...
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://searcher1/Searcher.svc/general" binding="basicHttpBinding" bindingConfiguration="SearchService" contract="remotehost.ISearch" name="SearchService" />
      <!--I manually added this-->
      <endpoint address="http://portal/Portal.svc/general" binding="basicHttpBinding" contract="remotehost.ISearch" name="RouterService" />
    </client>
  </system.serviceModel>
</configuration>


強調したいのですが、これはすべて機能しますが、思い通りには機能しません。これを思い描いているエレガントなセットアップにプッシュ/プル/カジョルできることはかなり確信していますが、初めてそれを説明するリソースやガイドを見つけることができないようです.

ヘルプ?


ここに来る前に私が相談した情報源:

Learning WCF: A Hands-on Guide, by Bustamante, Michele Leroux {978-0-5961-0162-6} (read cover to cover, and did all exercises)  
Windows Communication Foundation 4: Step By Step {978-0-7356-4556-1} (focused on chapter 14: Discovering Services and Routing Messages)  
msdn.microsoft.com/en-us/library/ms734712.aspx {WCF: Getting Started Tutorial}  
msdn.microsoft.com/en-us/gg465212 {what's new in WCF4: exercises 8 & 9, content bridging & routing}  
codeproject.com/Articles/146835/How-to-create-scalable-services-with-WCF-4-0-Route {How to create scalable services with WCF 4.0 Router and Discovery services}  
msdn.microsoft.com/en-us/library/dd795218.aspx {Hello World with the Routing Service}  
msdn.microsoft.com/en-us/library/ee517421.aspx {routing}  
  msdn.microsoft.com/en-us/library/ee517423.aspx {routing service overview}  
  msdn.microsoft.com/en-us/library/ee517418.aspx {routine service features}  
  msdn.microsoft.com/en-us/library/ee517422.aspx {routing intro}  
  msdn.microsoft.com/en-us/library/ee517420.aspx {routing contracts}  
msdn.microsoft.com/en-us/library/bb332338.aspx {wcf routing}  
msdn.microsoft.com/en-us/library/ms730158.aspx {more wcf routing}  
msdn.microsoft.com/en-us/library/ee354381.aspx {more wcf routing}  
dandcohen.wordpress.com/2010/03/02/wcf-4-routing-service-multicast-sample/ {WCF 4 Routing Service Multicast sample}  

更新: 2012 年 4 月 28 日:

私は自分がやりたいことをする方法を見つけました。まだ私が望んでいたほどエレガントではありませんが、仕事をやり遂げ、前進することができました.

基本的に、メイン サービスからインターフェイスを取得し、それを新しいサービスに実装して、ルーターまたはポータルなどと呼びます。新しいルーター/ポータル サービスで、メイン サービスへの新しいサービス参照を追加します。

これで、両方のサービスが同じインターフェイスを使用し、すべてのメソッドに対して同じシグネチャを持っているため、ポータル/ルーター サービスの wsdl をサード パーティ クライアントに渡すだけで、ポータル/ルーター サービスとの通信のみを許可できます。メインサービス。

さらに、複数のメイン サービスがある場合は、ポータル/ルーター サービスを使用して、リクエストを送信するメイン サービスを決定し、それらへの複数のサービス参照とプロキシを使用してジョブを送信できます。それは本当にうまくいきます。

基本的には手動のフロントエンド ルーティング サービスですが、細かい作業はスレッド モデルのメイン サービスで実行でき、ゲートキーピングの作業はポータル/ルーターで実行できるため、実際のリクエストのみが送信されるという利点があります。主要なサービスに対してのみ作業を許可し、ポータル サービスはその作業をどのように行うか、または行うかどうかを決定します。次のステップでは、新しいサービスの自動検出を追加したいと考えていますが、今のところ、手動​​構成は正常に機能しています。

誰かが見たいと思ってリクエストした場合は、私が思いついたもののソースコードを投稿できます.

4

1 に答える 1

0

基本的な問題は、サービスが使用しているサービス コントラクトについてルーターが何も認識していないことです。つまり、ユニバーサル コントラクト (メッセージ タイプを使用するコントラクト) を使用します。したがって、ルーターがクライアントのメタデータを自動生成する方法はありません。

あなたがする必要があるのは、メタデータを自分で、おそらく静的 WSDL ドキュメントとして提供し、その中の正しいアドレスを指定して、クライアントにこれを示すことです。

于 2012-04-19T06:19:38.487 に答える