.NET Web服务调用池?

发布于 2024-08-18 09:53:54 字数 408 浏览 8 评论 0原文

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

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

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

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

有没有办法让网络服务重复频繁地调用池?

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

在生产中,调用永远不会以这种速度进行,因此不会出现问题......但最好有一些代码允许测试工作,并限制或共享连接。

谢谢

I am writing acceptance tests to validate a system and it's data access is all done through web service calls.

Unfortunately, because I make so many calls, so quickly, I run into the following error

System.Net.Sockets.SocketException:
Only one usage of each socket address
(protocol/network address/port) is
normally permitted

I have locally cached as many of the calls as possible, but that's not enough. I can't fake or mock these calls. They have to be real for this level of tests to be valid.

Is there a way to get repeated frequent web service calls to pool?

Or to check if a connection can be made to the service prior to attempting the call, and wait until an available socket exists?

In production the calls are never made at this speed, so the issue won't arise...but it would be nice to have some code in place to allow for the tests to work, and throttle or share the connections.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安静 2024-08-25 09:53:55

一个简单的解决方案是通过让线程休眠一小段时间来减慢测试速度;比生产中的速度快,但比用完所有端口的时间短。

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

A simple solution would be to slow down your tests by making you thread sleep for a short time; faster than would be in production but shorter than what would use up all the ports.

No change in the app or the system.

大海や 2024-08-25 09:53:54

事实证明,一位同事已经有一个解决方案已在我们的电子商务网站上使用。您只需继承您的 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);
    }

}

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

Turns out, a co-worker had a solution already that was used on our e-com site. You just inherit from your web-service, override the GetWebRequest function with some different settings and you're done.

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);
    }

}

I'm guessing it uses more resources, but it doesn't fail.

温柔少女心 2024-08-25 09:53:54

MSDN 文章避免 TCP/IP 端口耗尽建议采用以下方法

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

您还应该检查您在测试拆卸中的每次调用后都正确关闭了连接。

或者,如果您不想进行任何配置更改,您可以扫描临时端口范围,如果没有空闲端口,请暂停并等待。一些要发布的文章 '

The MSDN Article Avoiding TCP/IP Port Exchastion recommends the following approaches

  • Increase the number of ephemeral ports available via the registry (that is, the ports allocated on the client to call the webservice
  • Reduce the TCP/IP timeout to free ports more quickly (again via the registry).

You should also check that you're closing the connections correctly after each call in the teardown of the test.

Alternativly, if you don't want to make any config changes, you could scan the ephemeral port range and if there are no ports free, pause and wait for some to be released. The article 'Detecting the next available, Free TCP port' has some example code that could be adapted for this purpose.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文