.NET webservice调用池?

时间:2010-01-14 20:47:13

标签: .net web-services connection-pooling socketexception

我正在编写验收测试以验证系统,并且它的数据访问都是通过Web服务调用完成的。

不幸的是,因为我拨打了这么多电话,所以很快就遇到了以下错误

  

System.Net.Sockets.SocketException:   每个套接字地址只有一种用法   (协议/网络地址/端口)是   通常允许

我在本地缓存了尽可能多的调用,但这还不够。我不能伪造或嘲笑这些电话。它们必须是真实的才能使这一级别的测试有效。

有没有办法让重复频繁的Web服务调用到池?

或者在尝试呼叫之前检查是否可以与服务建立连接,并等到可用的套接字存在?

在生产中,呼叫永远不会以这种速度进行,因此问题不会出现......但是有一些代码可以让测试工作,并限制或共享连接,这将是很好的。

由于

3 个答案:

答案 0 :(得分:2)

事实证明,一位同事已经在我们的e-com网站上使用了解决方案。您只需从Web服务继承,使用一些不同的设置覆盖GetWebRequest函数,就可以了。

class SafeMyWebService : MyWS.Service
{
    private static int _lastBindPortUsed;

    protected override WebRequest GetWebRequest(Uri uri)
    {
        var webreq = base.GetWebRequest(uri) as HttpWebRequest;

        webreq.KeepAlive = true;
        webreq.ProtocolVersion = HttpVersion.Version10;
        webreq.ServicePoint.MaxIdleTime = 10 * 1000; // milliseconds 
        webreq.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
        webreq.Timeout = 2000;
        webreq.ConnectionGroupName = "MyConnectionGroupName";

        return webreq;
    }

    public static IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
    {
        int port = Interlocked.Increment(ref _lastBindPortUsed);
        Interlocked.CompareExchange(ref _lastBindPortUsed, 5001, 65534);

        return remoteEndPoint.AddressFamily == AddressFamily.InterNetwork 
            ? new IPEndPoint(IPAddress.Any, port) 
            : new IPEndPoint(IPAddress.IPv6Any, port);
    }

}

我猜它会使用更多资源,但它不会失败。

答案 1 :(得分:1)

MSDN文章Avoiding TCP/IP Port Exchastion建议采用以下方法

  • 增加通过注册表提供的临时端口数(即,在客户端上分配的端口以调用Web服务
  • 减少TCP / IP超时以更快地释放端口(再次通过注册表)。

您还应检查在拆除测试后每次通话后是否正确关闭连接。

另外,如果您不想进行任何配置更改,您可以扫描临时端口范围,如果没有可用的端口,请暂停并等待某些端口释放。文章“Detecting the next available, Free TCP port”有一些示例代码可以用于此目的。

答案 2 :(得分:0)

一个简单的解决方案是通过让你在短时间内进行线程睡眠来减慢测试速度;比生产中的更快但比用完所有端口的更短。

应用程序或系统没有变化。