WCF 4路由多播配置挫折

时间:2012-04-13 21:05:55

标签: wcf c#-4.0 routing multicast

我多年来一直使用stackoverflow.com作为专业程序员的资源。我会说,当我在谷歌上搜索一些东西时,有10次中有8次,我在这里指出了一个问题和答案,当这种情况发生时我总是松了一口气,因为我知道我将要找到我需要的信息。

关于使用WCF技术设置路由服务,我一直在努力想象(我认为是)一个简单的问题。我在这里浏览了类似标题的问题,并且我已经咨询了很多资源(关于这个主题的实际书籍以及网站)试图解决这个问题,但没有用。

简而言之,我想设置一个具有以下布局的系统:

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

客户端:获取门户网站的服务参考,能够在终端服务中调用功能
门户/路由器:从客户端获取请求,并将它们发送到多播设置中的端点服务
end-point-services1..n :从客户端获取请求,通过门户网站路由,处理搜索事物的请求,并响应或在数据库中记录数据以便稍后检查

我100%能够启动并运行路由服务。我能够遵循的最成功的模型在WCF4的新内容中概述了:练习8&amp; 9,内容桥接&amp;路由&#34; (msdn.microsoft.com/en-us/gg465212)和#34; Hello World与路由服务&#34; (msdn.microsoft.com/en-us/library/dd795218.aspx)但我使用过我所咨询过的所有来源(见下文)中的点点滴滴。

基本上,令我感到沮丧的是,我希望客户端(第三方)能够仅向门户服务添加Web服务引用(或者,最坏的情况下,使用svcutil.exe方法),并且在他们的设置上完成。通过该引用,他们将引用他们想要在所有场景中调用的所有函数/方法。我看过的模型需要2个引用,一个到实际服务,一个到路由器,然后强制客户端在其设置中专门调用路由器。我的其他任何尝试都没有使这个特定的设置工作,已经有效。

您对此的帮助将非常赞赏。


以下是我的工作模式的简化版本 几乎 正在做我想要的事情:

<小时/> (注意,所有服务都在IIS中托管)

PORTAL SERVICE(和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>

<小时/> 客户端(这一切都出错了)

只有我能够让它做我想做的事情,就是向搜索服务添加一个Web服务引用(名为&#34; remotehost&#34;),然后手动将客户端端点添加到应用程序路由器的.config文件,并强制客户端代码使用它,它已经拥有的直接链接的INSTEAD给搜索者

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>

<小时/> 我想强调一下,这一切都是可行的,但它并没有按照我想要的方式运作。我相当肯定我可以推送/拉/ this这个我想象的优雅设置,但我似乎找不到第一次引导我完成它的资源或指南。

帮助?


我来之前咨询的来源:

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-04-28:

我找到了一种方法来做我想做的事。它仍然没有我想要的那么优雅,但它完成了工作,并让我继续前进。

基本上,从主服务获取接口,并在新服务中实现它,称之为路由器或门户,或其他任何东西。在新的路由器/门户服务中,向主服务添加新的服务引用。

现在,两个服务都使用相同的接口,并且所有方法都有相同的签名,因此您可以将门户/路由器服务wsdl提供给第三方客户端,并且只允许您的门户/路由器服务与主要服务沟通。

此外,如果您有多个主服务,则可以使用门户/路由器服务来决定向哪些主要服务发送请求,使用多个服务引用,以及代理向前发送作业。它的效果非常好。

它基本上是一个手动的前端路由服务,但美观的是,详细的工作可以在线程模型的主要服务中完成,而守门工作可以在门户/路由器上完成,所以只有实际请求被发送到主服务,允许他们只做工作,门户服务决定他们是如何或是否得到这项工作。下一步我想添加它自动发现新服务,但是现在,手动配置工作正常。

我可以发布我想出的源代码,如果有人想看到它并请求它。

1 个答案:

答案 0 :(得分:0)

根本问题是路由器对服务正在使用的服务合同一无所知 - 它使用通用契约(使用Message类型的契约)。因此,路由器无法为客户端自动生成元数据。

您需要做的是自己提供元数据,可能作为静态WSDL文档,其中包含正确的地址并将客户端指向此