質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

2427閲覧

WCFクライアントからの長時間セッションで発生するNLBのタイムアウトを回避したい

ware

総合スコア27

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2022/12/21 13:21

編集2022/12/22 09:31

前提

オンプレサーバからAWSのEC2にシステムを移行しています。
AWSのEC2上でWCFサービスを動かし、社内PCにインストールされたWCFクライアントから接続します。
(エンドポイントのバインド型はBasicHttpBinding)
EC2とクライアントの間にNetwork Load Balancerがあるのですが、NLBは350秒でアイドルタイムアウトが発生するため、長時間セッションだと途中で通信が切られてしまいます。

実現したいこと

AWSのドキュメントに「セッションを維持するためにはアプリケーション側でHello Packetを送るなどの対応が必要です。」とあるのですが、WCF構成エディタを見ても何を設定すれば良いのか分かりません…。

構成ファイル(App.config)に何かを追加すればよいのでしょうか?
構成ファイルではない場合、どのような対応をすれば良いのか教えていただきたいです。

発生している問題・エラーメッセージ

System.Net.WebException: 接続が切断されました: 接続が予期せずに閉じられました。

試したこと

NLB経由ではなく、直接EC2のWCFサービスに接続する形だとエラーは発生しません。
なので、NLBのアイドルタイムアウトな事は間違いなさそうです。

クライアントのレジストリ追加
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
KeepAliveTime 0x000186a0(100000)
KeepAliveInterval 0x000186a0(100000)
→解決しませんでした。

クライアントプログラムに以下のコードを追加
var sp = System.Net.ServicePointManager.FindServicePoint(address.Uri);
sp.SetTcpKeepAlive(true, 30000, 30000);
→解決しませんでした。

KeepAliveをキーワードに対応方法を調査
https://tsmatz.wordpress.com/2009/09/24/wcf/
https://learn.microsoft.com/ja-jp/dotnet/framework/wcf/load-balancing
BasicHttpBinding では、既定で HTTP の KeepAlive の設定がおこなわれている…?
(ではなぜ、切断されるのか…。NLBのログの確認方法を調査中。)

補足情報

VisualStudio2017
.NetFramework4.7.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/12/29 00:59

質問者さん、その後無言ですがどうなりましたか? 進展があったら書いてください。ギブアップしたとかならクローズしてください。無言で放置は NG です。
guest

回答1

0

ベストアンサー

ググって調べただけですが以下の記事が参考になりませんか?

【図解】TCP Keep-Alive/http Keep-Aliveの仕組みと違い ~Client/Serverの挙動とメリット,設定~
https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/keepalive-tcp-http/

実際に試して確認したわけではないのでハズレだったスミマセン。

TCP KeepAlive をキーワードにググるといろいろヒットするので自分でもやってみてください。


【追記】

アプリで解決したという記事を見つけたので紹介しておきます。

.NET: How to send TCP Keep Alive packets while downloading from HTTP API?
https://stackoverflow.com/questions/63193055/net-how-to-send-tcp-keep-alive-packets-while-downloading-from-http-api

これもググって調べただけで検証したわけではありませんが。

投稿2022/12/21 22:50

編集2022/12/22 00:31
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ware

2022/12/22 08:24

SurFerOnWwwさん 回答ありがとうございます。 お礼が遅くなってしまってすいません。 >【図解】TCP Keep-Alive/http Keep-Aliveの仕組みと違い ~Client/Serverの挙動とメリット,設定~ こちらを参照してTCP Keep-Aliveの設定をすればいいのかと考えて、レジストリを追加してみました。 Wiresharkでパケットをキャプチャしてみたのですが、送られている様子が無く… >.NET: How to send TCP Keep Alive packets while downloading from HTTP API? こちらを参照してテストプログラムを作成してみました。 ----------------- public partial class Form1 : Form { // サービス参照したウェブサービスインスタンスを保存しておくプライベートフィールド private ServiceReference1.TestServiceClient _WS = null; public Form1() { InitializeComponent(); } /// <summary> /// ウェブサービスインスタンスの作成 /// </summary> /// <returns></returns> public ServiceReference1.TestServiceClient GetService() { var address = new System.ServiceModel.EndpointAddress("http://xxx.xxx.xxx.xxx/TestWS/TestService.svc"); //WebサービスのステータスがFaultedの場合、一度アボートさせる if (_WS != null && _WS.State == System.ServiceModel.CommunicationState.Faulted) { _WS.Abort(); _WS = null; } if (_WS == null || _WS.State == System.ServiceModel.CommunicationState.Closed) { _WS = null; _WS = new ServiceReference1.TestServiceClient(); _WS.Endpoint.Address = address; // TCP Keep Aliveテスト var sp = System.Net.ServicePointManager.FindServicePoint(address.Uri); sp.SetTcpKeepAlive(true, 30000, 30000); } return _WS; } public virtual async void StartProgress() { var task = GetService().GetBigDataAsync(2020); var result = await task; } private void button1_Click(object sender, EventArgs e) { StartProgress(); } ----------------- ↑Wiresharkでパケットキャプチャしてみたのですが、送られている様子が無く… 書き方を間違っている気もします。 また、↓のサイトを参照したところ 「既定では、BasicHttpBinding は、メッセージの接続 HTTP ヘッダーで Keep-Alive 値を送信することで、サポートするサービスにクライアントが永続的な接続を確立できるようにします。 」 https://learn.microsoft.com/ja-jp/dotnet/framework/wcf/load-balancing とあり、BasicHttpBindingを使えばKeep-Aliveの設定が出来ているというようにも読めます。 じゃあWiresharkでキャプチャできない&切断されるのはなぜだろうという事になりますが‥。 何か気付く点がありましたら、教えていただけると嬉しいです。
退会済みユーザー

退会済みユーザー

2022/12/29 00:58

質問者さん、その後無言ですがどうなりましたか? 進展があったら書いてください。ギブアップしたとかならクローズしてください。無言で放置は NG です。
ware

2023/01/04 03:14

SurferOnWwwさん、ありがとうございます。 調査に時間がかかり、閉じるのが遅くなってしまいすいません。 教えていただいた記事を参考にTCP KeepAliveを送る以下のコードを追加したところ、問題が解決しました。 // TCP Keep Aliveテスト var sp = System.Net.ServicePointManager.FindServicePoint(address.Uri); sp.SetTcpKeepAlive(true, 30000, 30000); ありがとうございます。 (補足) TCP Keep-Aliveのコードを追加してもWiresharkでKeepAliveがキャプチャできない&切断される問題は、クライアントにインストールされていたセキュリティゲートウェイ製品の問題だと分かりました。 セキュリティゲートウェイ製品のホワイトリストにNLBのアドレスを追加したところ、KeepAliveがキャプチャできるようになり、350秒のタイムアウトも解決できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問