web-dev-qa-db-ja.com

WCFとTCPでキープアライブ?

TCP(netTCP)を介してprotobuf.netと通信し、場合によっては証明書と通信する高度なWCFサービスをホストするWindowsサービスがあります。

receiveTimeoutは無限に設定されており、非アクティブが原因で接続が切断されることはありません。しかし、私が理解していることから、接続がとにかく切断される可能性があるため、クライアントが維持するために9分ごとに呼び出す単純な双方向keepaliveサービスメソッドを作成しました接続は生きています。接続が切断されないことが非常に重要です。

これは正しい方法ですか?または、receiveTimoutが無限に設定されているため、単にライブキープを削除できますか?

編集:WCFサービスの現在のapp.config: http://1drv.ms/1uEVKIt

13
Banshee

いいえ。これは広く誤解されており、残念ながら多くの誤った情報があります。

まず、「無限」は一種の半有効な値です。 「Infinite」をTimeSpan.MaxValueまたはint.MaxValueに変換する2つの特別な構成シリアライザーがあります(したがって、実際には「無限」ではありません)が、WCFのすべてがこれを認識しているわけではないようです。したがって、タイムアウトを時間値で明示的に指定することが常に最善です。

次に、WCFは「信頼できるセッション」と呼ばれるものを提供するため、サービスに「キープアライブ」メソッドは必要ありません。 <reliableSession enabled="true" />を追加すると、WCFは「インフラストラクチャメッセージ」を通じて独自のキープアライブメカニズムを提供します。

独自の「キープアライブ」メカニズムを使用することで、サービスの負荷が実質的に2倍になり、実際には、解決するよりも多くの問題を作成できます。

第三に、信頼できるセッションを使用する場合は、inactivityTimeoutreliableSession設定を使用します。これは2つのことを行います。まず、インフラストラクチャ(キープアライブ)メッセージが送信される頻度を制御します。タイムアウト値の半分で送信されるため、18分に設定すると、9分ごとに送信されます。次に、非アクティブタイムアウト内にインフラストラクチャまたは操作メッセージ(つまり、データコントラクトの一部であるメッセージ)が受信されない場合、問題が発生した可能性があるため(一方がクラッシュした、ネットワークに問題があるなど)、接続が中止されます。 。)。

receiveTimeoutは、接続が中止されるまでに操作メッセージを受信できない最大時間です(デフォルトは10分)。これを大きな値(Int32.MaxValueは24日近く)に設定すると、接続が確立されたままになり、inactivityTimeoutが小さい値(ここでもデフォルトは10分)に設定されます(時間はネットワークルーターが非アクティブから接続をドロップするまでの最大時間の2倍)は、接続を維持します。

WCFがこれらすべてを処理します。次に、接続中止メッセージをサブスクライブするだけで、実際の理由(アプリのクラッシュ、ネットワークタイムアウト、クライアントの電源喪失など)で接続が切断されたことを確認し、接続を再作成できます。

さらに、順序付けられたメッセージが必要ない場合は、ordered="false"を設定します。これにより、信頼できるセッションのオーバーヘッドが大幅に削減されます。デフォルトはtrueです。

注:inactivityTimeoutの期限が切れるまで(または接続を使用しようとするまで)、接続中止イベントを受信しない場合があります。これに注意し、それに応じてタイムアウトを設定してください。

インターネットでのほとんどの推奨事項は、receiveTimeoutとinactivityTimeoutの両方をInfiniteに設定することです。これには2つの問題があります。最初のインフラストラクチャメッセージがタイムリーに送信されないため、ルーターが接続を切断します...独自のキープアライブを実行する必要があります。次に、非アクティブタイムアウトが大きいということは、接続が合法的に切断されたときを認識しないことを意味し、障害がいつ発生したかを知るには、そのpingの中止に依存する必要があります。これはすべて完全に不要であり、実際にはサービスの信頼性をさらに低下させる可能性があります。

これも参照してください: WCF NetTcp Duplex Reliable Sessionを正しく構成するにはどうすればよいですか?

39