8

我有一个从我的应用程序连接到的远程 WCF Web 服务。

应用程序可能在具有多个 IP 地址(或多个物理网络接口)的服务器上运行

我需要确保我可以控制用于出站请求的 IP 地址,而不是按照常规度量规则仅使用“首选”接口。

这样做的原因是软件的多个副本将在同一台机器上运行,每个副本都绑定到特定的 IP 地址以进行自己的操作,并且连接到的远程服务需要知道正在使用哪一个来连接回稍后再进行(因为地址错误意味着连接到错误的服务)

对于传统的 ASMX 服务,这是通过覆盖GetWebRequest(Uri uri)为服务生成的部分类来完成的。但我根本不知道如何用 WCF 做到这一点。

不相关的 SO 帖子中,MVP @JohnSaunders 建议通过接管 WCF 使用的整个传输机制来实现这一点。但我还没有弄清楚如何做到这一点。

4

3 回答 3

4

这是一个棘手的问题,WCF 似乎并不能很好地解决这个问题。

.NET 框架中似乎直接处理客户端地址问题的唯一组件是ServicePoint类。具体来说,它有一个BindIPEndPointDelegate属性,可让您控制它如何选择客户端 IP。该属性的文档包括:

一些负载平衡技术要求客户端使用特定的本地 IP 地址和端口号,而不是IPAddress.Any(或IPAddress.IPv6Any对于 Internet 协议版本 6)和临时端口。你BindIPEndPointDelegate可以满足这个要求。

因此,您应该能够在如下代码中修改与您的 URL 关联的服务点:

var servicePoint =  ServicePointManager.FindServicePoint(
    new Uri("http://contoso.com/service.svc"));

servicePoint.BindIPEndPointDelegate =
    (sp, remote, retryCount) => new IPEndPoint(address, portNumber);

显然,这种代码要求您的类了解协议和客户端将与之通信的端点地址。将此逻辑设置为可以应用于您的客户端通道的客户端行为可能是最合适的。

于 2013-07-16T11:00:57.363 回答
0

您可以使用消息属性 (HttpRequestMessageProperty) 将 HTTP 标头添加到任何传出请求。您需要创建一个“范围”,其中属性将添加到当前的“操作上下文”中,并将该属性与您想要的所有标题一起附加到上下文的传出消息属性中。

请看这个:

如何覆盖-getwebrequest-method-using-service-reference-instead-of-web-reference-in-wcf

于 2013-07-16T10:23:43.163 回答
0

使用这个:新类:

using System.Web.Services.Protocols;
using System.Windows.Forms;
using System;

public static class ExtensionMethods
{
    public static string ApplyServerURL(this SoapHttpClientProtocol service)
    {
        try
        {
            string name = service.GetType().Name;
            return string.Format("{0}{1}.svc", Settings.Instance.ServerAddress, name);
        }
        catch
        { return string.Empty; }
    }
}

现在是这样的:

YourService us = new YourService();
us.Url = us.ApplyServerURL();
于 2013-07-16T10:29:50.140 回答