.NET веб-сервис пулов вызовов? - PullRequest
4 голосов
/ 14 января 2010

Я пишу приемочные тесты для проверки системы, и доступ к данным осуществляется через вызовы веб-службы.

К сожалению, из-за того, что я так часто звоню, я сталкиваюсь со следующей ошибкой

System.Net.Sockets.SocketException: Только одно использование каждого адреса сокета (протокол / сетевой адрес / порт) обычно разрешено

Я локально кэшировал как можно больше вызовов, но этого недостаточно. Я не могу подделать или высмеять эти звонки. Они должны быть реальными, чтобы тесты такого уровня были действительными.

Есть ли способ получать повторные частые вызовы веб-службы в пул?

Или проверить, можно ли установить соединение со службой перед попыткой вызова, и подождать, пока существует доступный сокет?

В работе вызовы никогда не выполняются с такой скоростью, поэтому проблема не возникнет ... но было бы неплохо иметь некоторый код для работы тестов, а также для регулирования или разделения соединений.

Спасибо

Ответы [ 3 ]

2 голосов
/ 15 января 2010

Оказывается, у сотрудника уже было решение, которое использовалось на нашем сайте электронной коммерции. Вы просто наследуете от своего веб-сервиса, переопределяете функцию 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 голос
/ 14 января 2010

Статья MSDN Как избежать использования порта TCP / IP рекомендует следующие подходы

  • Увеличение количества временных портов, доступных через реестр (то есть портов, выделенных на клиенте для вызова веб-службы
  • Сокращение времени ожидания TCP / IP для освобождения портов (снова через реестр).

Вы также должны проверить, правильно ли вы закрываете соединения после каждого вызова в завершении теста.

В качестве альтернативы, если вы не хотите вносить какие-либо изменения в конфигурацию, вы можете отсканировать диапазон временных портов и, если нет свободных портов, приостановить и дождаться освобождения некоторых из них. В статье « Определение следующего доступного свободного порта TCP » приведен пример кода, который можно адаптировать для этой цели.

0 голосов
/ 15 января 2010

Простым решением было бы замедлить ваши тесты, заставив вас ненадолго спать; быстрее, чем было бы в производстве, но короче, чем то, что использовало бы все порты.

Без изменений в приложении или системе.

...