7

最終的に、WCF デュプレックス Silverlight 4 クライアント404 Not Foundは、ポーリングが WCF サービスから Silverlight クライアントに送信された直後に、ポーリング メッセージのエラーを受け取り始めます。これは、2 回目のポーリングで発生する場合があり、接続が数時間または数日かかることもありますが、ほとんどの場合、最初の数分で失敗します。

! そして興味深いのは、MaxMessagesPerPollデュプレックス モードを使用している場合の既知の Silverlight 4 のバグのような問題であり、解決策はここここで説明されていますが、私はSingleMessagePerPollモードを使用しています。とにかくClientStack、提案どおりに使用してみましたが、何も変わりませんでした。

一般的な流れ:

  1. SL クライアントが WCF サービス メソッドを実行し、応答を受信
  2. 次に、すぐにSL クライアントがポーリング メッセージをサービスに送信し始め、2 番目または Ns のポーリング メッセージの例外を取得します。

    System.Net.WebException: リモート サーバーがエラーを返しました: NotFound

  3. Fiddler404は、ポーリング メッセージに対して空の応答のみを表示します
  4. その後、クライアント Channel Faulted イベントが発生しました

このような障害が発生した後、SL クライアントを再接続しようとしています。単一の再接続再試行フロー:

  1. Faultedイベントを処理する
  2. 次のようなすべてのチャンネル イベントの登録を解除しますClosed/Closing/Opened/Opening
  3. を使用して正しい方法でチャネルを閉じますtry { close } catch { abort }
  4. 以下のすべては、新しいスレッド ポール スレッドにあります:(私はこれがわずかに安定して動作することを発見しました -この記事を参照してください)
  5. 45 ~ 70 秒待ちます
  6. 同じDuplexChannelFactory<T>インスタンスを使用して新しいチャネルを作成し、ログ記録のみを目的としてすべてのチャネル イベントをサブスクライブします。
  7. WCF サービス メソッドの実行

1 ~ 10 回の再試行 (~1 ~ 10 分) の後、クライアントは最終的にサーバーに接続し、通常のポーリングを続行します。

WCF サービス ログを見ると、すべての cleint リクエストが例外なく処理されていることがわかります。そのため、Silverlight クライアント側で何かが発生しているようです。

一般的な情報:

  • .NET フレームワーク 4.0
  • PollingDuplex
  • 非同期 WCF メソッド
  • IIS 6.0 がホストする WCF サービス
  • Silverlight 4 クライアント
  • クライアント OS: Windows XP SP2
  • サーバー OS: Windows 2003 R2 SP2
  • NTLM 認証
  • DuplexMode: SingleMessagePerPoll
  • サービスが機能する前に要求/応答を行う他の WCF サービスがあり、二重接続を使用しません
  • SL クライアント サービスでは、すべてを UI に記録しているので、すべてのイベント フローを確認し、特定のイベントごとに時間を取ります。
  • IIS ログ、サーバー イベント ログにエラーなし

クライアント:

var binaryBinding = new BinaryMessageEncodingBindingElement();
binaryBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;

var httpbindingElement = new HttpTransportBindingElement
{
    MaxReceivedMessageSize = 131072
};

var pollingDuplexBindingElement = new PollingDuplexBindingElement
{
    ClientPollTimeout = new TimeSpan(0, 0, 1, 30),
    InactivityTimeout = new TimeSpan(0, 8, 0, 0),
};


_binding = new CustomBinding(
           pollingDuplexBindingElement,
           binaryBinding,
           httpbindingElement)
       {
           SendTimeout = new TimeSpan(0, 0, 0, 45),
           CloseTimeout = new TimeSpan(0, 0, 0, 25),
           ReceiveTimeout = new TimeSpan(0, 8, 0, 0),
           OpenTimeout = new TimeSpan(0, 0, 0, 45)
       };


httpbindingElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
var endpoint = new EndpointAddress(_endpointAddress);
_channelFactory = new DuplexChannelFactory<TWebService>(
                       new InstanceContext(instanceOfClientServiceClass), 
                       _binding, 
                       endpoint);


// then this factory used to create a new channels
// Also for a new channel I'm setting OpTimeout
var contextChannel = newChannel as IContextChannel;
if (contextChannel != null)
{
   contextChannel.OperationTimeout = TimeSpan.FromSeconds(45);
}

サーバ:

  • WCF、PerSession、マルチスレッド
  • すべてがスレッドセーフです
  • 実行中のサーバー サービス例外なし
  • たくさんのログがあるので、サービスで何が起こっているかがわかります
  • すべての WCF トレースは switchValueAllで有効化されており、疑わしいものはありません
<binding name="customName"
             sendTimeout="00:01:00"
             receiveTimeout="08:00:00"
             openTimeout="00:01:00"
             closeTimeout="00:00:35">
     <pollingDuplex
         inactivityTimeout="08:00:00"
         serverPollTimeout="00:01:00" />
         <binaryMessageEncoding />
           <httpTransport authenticationScheme="Ntlm"
                          maxReceivedMessageSize="131072">              
         </httpTransport>
</binding>

<behavior name="customBehavior">
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceThrottling
             maxConcurrentCalls = "500"
             maxConcurrentSessions = "500"
             maxConcurrentInstances = "500" />
</behavior>
4

2 に答える 2

3

すべてが正常に機能しているように見える場合、これはおそらくネットワーク インフラストラクチャ/構成の問題です (DNS 構成など)。ローカルで実行している場合、またはホスト名の代わりに IP アドレスを使用している場合、同じ問題が発生しますか?

IIS のサイトに複数のバインドが構成されている場合にも、同様の問題が発生する可能性があります (詳細については、http: //blogs.msdn.com/b/rampo/archive/2008/02/11/how-can-wcf-supportを参照してください)。 -multiple-iis-binding-specified-per-site.aspx )

もう 1 つのことは、サーバーからクライアントへの通信方法です。クライアントをループで反復し、コールバック メソッドを 1 つずつ呼び出すと、404 として表示されるタイムアウトが発生する場合があります。通常、コールバックはバックグラウンド スレッドで呼び出す必要があります (クライアントごとに 1 つ)。

通信の方法によっては、デッドロック (サービスとの間のメッセージ/コールバックの送受信に UI スレッドが関与している場合) が原因である可能性もあります。

于 2012-12-21T11:34:56.777 に答える
1

このStackOverflowの投稿で説明されている問題を調査しているときに、PerSession WCFサービスに対して2回呼び出された静的コンストラクターは、以前に指定されたものではなく、単一のワーカープロセスを使用するように基になる構成Polling Duplexを切り替えると、安定して動作し始めることがわかりました。このサーバーを所有していないため、以前に設定された理由はわかりませんが、とにかくこれが現在の状況です。同じマシンで起動された複数のSilverlightクライアントは安定して動作し、ポーリングはポーリングを行い、エラーは発生しません。 IISが再起動してリサイクルします...IISAppPool224041

詳細については、パフォーマンスアプリケーションプールの設定を参照してください。

TL; DR: IISでホストされているWCFが複数のワーカープロセスを持つAppPoolにある場合、ポーリングデュプレックスが不安定になります。したがって、高負荷の場合、IISは2番目のプロセスを開始し、2番目のプロセスでもWCFサービスインスタンスの作成を開始します。そのため、あるプロセスでクライアントセッションが作成されたときに、現在のプロセスを認識していない別のプロセスにポーリングが到達することがあるという状況に遭遇しました。接続/セッションなので、そのようなメッセージと接続障害全体の拒否を開始します。

したがって、設計によるデュプレックスのポーリングは、単一のIISサーバーとAppPoolのスコープ内の複数のプロセス間でスケーラブルではありません。つまり、複数のワーカープロセスがある場合、これはWebGarden環境であり、デュプレックスはWebファームとガーデン間でスケーラブルではありません。

于 2012-12-25T14:45:50.130 に答える