4

システムを検証するための受け入れテストを書いていますが、そのデータ アクセスはすべて Web サービス呼び出しを介して行われます。

残念ながら、私は非常に多くの呼び出しをすばやく行うため、次のエラーが発生します

System.Net.Sockets.SocketException: 通常、各ソケット アドレス (プロトコル/ネットワーク アドレス/ポート) の 1 つの使用のみが許可されます

できるだけ多くの呼び出しをローカルにキャッシュしましたが、それだけでは十分ではありません。これらの呼び出しを偽ったり、嘲笑したりすることはできません。このレベルのテストが有効であるためには、それらが本物でなければなりません。

プールへの Web サービス呼び出しを頻繁に繰り返す方法はありますか?

または、呼び出しを試みる前にサービスに接続できるかどうかを確認し、利用可能なソケットが存在するまで待ちますか?

本番環境では、呼び出しがこの速度で行われることはないため、問題は発生しません...ただし、テストが機能するようにコードを配置し、接続を調整または共有すると便利です。

ありがとう

4

3 に答える 3

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

}

より多くのリソースを使用すると思いますが、失敗しません。

于 2010-01-15T14:42:22.867 に答える
1

TCP / IPポートの交換を回避するMSDNの記事では、次のアプローチを推奨しています。

  • レジストリを介して使用可能なエフェメラルポート(つまり、Webサービスを呼び出すためにクライアントに割り当てられたポート)の数を増やします。
  • TCP / IPタイムアウトを減らして、ポートをより迅速に解放します(これもレジストリを介して)。

また、テストの分解で各呼び出しを行った後、接続が正しく閉じていることを確認する必要があります。

または、構成を変更したくない場合は、エフェメラルポートの範囲をスキャンし、空きポートがない場合は、一時停止して、一部が解放されるのを待ちます。記事「次に利用可能な空きTCPポートの検出」には、この目的に適合させることができるいくつかのサンプルコードがあります。

于 2010-01-14T20:55:51.063 に答える
0

簡単な解決策は、スレッドを短時間スリープ状態にしてテストを遅くすることです。本番環境よりも高速ですが、すべてのポートを使い果たすよりも短くなります。

アプリやシステムに変更はありません。

于 2010-01-14T21:22:28.950 に答える