wcf - 指定与 WCF 客户端一起使用的传出 IP 地址

标签 wcf ip-address wcf-binding wcf-client

如何定义 WCF 客户端在调用 WCF 服务时使用的 LocalEndPoint(如果客户端计算机有多个 IP 地址)?

我有一台位于 DMZ 中的计算机,有两个 IP 地址,可以通过来 self 们位于外部服务提供商的网络服务器的 VPN 连接穿过防火墙到达外部 IP 地址。在此计算机上运行基于 WCF 和 Unity 的自定义应用程序服务器,该服务器应充当代理或应用程序级网关 (ALG)。它应接受来自 Web 服务器的服务调用,并使用 wcf 客户端工厂重新生成服务调用,将它们转发到 LAN 中的真实应用服务器。

使用 wcf 客户端工厂在此代理上重新创建服务调用时,wcf 客户端应使用该计算机的第二个内部 IP 地址,因为只有来自此内部 IP 地址的消息才被允许通过防火墙到达 LAN 中的应用程序服务器。不幸的是,我们的 wcf 客户端代理始终选择使用第一个“外部”IP 地址创建传出消息。我正在寻找一种方法来显式设置 wcf 客户端代理使用的 IP 地址。

我只能找到一个允许定义 LocalEndPoint 或 ClientBaseAddress 的 WCF 绑定(bind)元素:CompositeDuplexBindingElement。据我从文档中了解到,此属性旨在告诉服务器将异步回复消息发送到何处,因此它是与我正在寻找的设置不同的设置。

知道我能做些什么来找到可行的解决方案吗?

提前感谢您提供任何有用的建议!!

这似乎是一个类似的问题,只是使用 TcpClient/Sockets 而不是 WCF: Specify the outgoing IP address to use with TCPClient / Socket in C#

还有另一个,这次是关于 SoapClient: Binding a new SoapClient to a specific IP address before sending outgoing request

最佳答案

我自己很难找到这个问题的答案,所以我会分享我的解决方案,以防其他人过来。

下面是返回 WCF SoapService 的方法。该代码将尝试使用特定的 IP(如果可用)。我做了这个检查,让它在测试机器上也能正常工作。

    public static proposalSoapClient getService()
    {
        string serviceurl = "http://somesite.dk/proposal.asmx";
        var localIpAddress = IPAddress.Parse("123.123.123.123");
        var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));

        var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
        var endpoint = new EndpointAddress(serviceurl);
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));
        servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
        return new proposalSoapClient(binding, endpoint);
    }

此外,当我在测试服务器上时,我必须使用代理才能访问该服务。 (我在有权访问该服务的机器上使用 fiddler 作为代理)。下面是相同的代码,但在测试服务器上添加了代理部分。

    public static proposalSoapClient getService()
    {
        string serviceurl = "http://somesite.dk/proposal.asmx";
        var localIpAddress = IPAddress.Parse("123.123.123.123");
        var hasLocalAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Any(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.Equals(localIpAddress));

        var binding = new System.ServiceModel.BasicHttpBinding("proposalSoap"); //name of binding in web.config
        var endpoint = new EndpointAddress(serviceurl);
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(new Uri(serviceurl));

    #if DEBUG
        Uri proxyUri = new Uri("http://someothersite.dk:8888");
        binding.ProxyAddress = proxyUri;
        binding.BypassProxyOnLocal = false;
        binding.UseDefaultWebProxy = false;
        servicePoint = ServicePointManager.FindServicePoint(serviceurl, new WebProxy(proxyUri, false));
    #endif

        servicePoint.BindIPEndPointDelegate = (sp, rm, retryCount) => { return new IPEndPoint(hasLocalAddress ? localIpAddress : IPAddress.Any, 0); };
        return new proposalSoapClient(binding, endpoint);
    }

关于wcf - 指定与 WCF 客户端一起使用的传出 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3249846/

相关文章:

python - Python SimpleXMLRPCServer 中客户端的 IP 地址?

c# - 给定 IP 地址和子网掩码,如何计算 CIDR?

c# - ASP.NET 的 WCF 流问题

c# - 为每个派生类避免 KnownType 属性的普遍接受的方法

c# - WCF 客户端 `using` block 问题的最佳解决方法是什么?

c# - 仅具有托管代码和 WCF 服务的调试器中的 AccessViolationException

python - 更改selenium中的IP地址

c# - 在 ServiceModel 客户端配置部分找不到引用契约(Contract)的默认端点元素......................

c# - WCF 客户端 : First call fails, 第二次调用成功

c# - 并行调用服务方法