はじめに
MagicOnion の StreamingHub を利用している際にクライアント側でインターネットの接続を切っても、
サーバ側からクライアントの終了を即時に検知することが出来ないでいました。。
僕の環境ではその挙動でも問題がなかったので放置していたのですが、
他にも悩んでいる方がいるようだったので、調査することにしました
その結果、どうやら gRPC の keepalive の設定を行うことで対策出来そうでした
今後も keepalive の設定をすることはありそうなので記事として残すことにしました
動作環境
-
.NET Core サーバ
- ASP.NET Core 2.2
- MagicOnion 2.1.0(2.1.2)
-
Unity クライアント
- Unity 2019.1.4f1
- MagicOnion 2.1.0(2.1.2)
- grpc_unity_package.1.22.0-dev.zip
- macOS Mojave 10.14.5
keepalive 関連の gRPC チャンネルのオプション
分かりやすいドキュメントを発見することが出来なかったため、
gRPC Channel に設定可能なコンフィグは 公式のリンク を参照しました
コンフィグを一通り確認したところ keepalive 周りの設定を行うのに、
必要となりそうな主要なオプションは 3つありました
名前 | 説明 |
---|---|
grpc.keepalive_time_ms | ping の間隔 (ms単位) |
grpc.keepalive_timeout_ms | ping で許容する応答時間 (ms単位) |
grpc.http2.min_time_between_pings_ms | ping を連続で送信可能な最小間隔 (ms単位) |
grpc.http2.min_time_between_pings_ms
には grpc.keepalive_time_ms
と grpc.keepalive_timeout_ms
を足した値とかを設定しておくと良い気がします
gRPC チャンネルに keepalive 関連のオプションを設定する
クライアント側もサーバ側も同一値を設定したのですが、
念の為、実際に設定した際の コード について両者記載しておきます
Unity クライアント側
// 各種 keepalive 関連のオプションを設定する
List<ChannelOption> options = new List<ChannelOption> {
new ChannelOption("grpc.keepalive_time_ms", 2000),
new ChannelOption("grpc.keepalive_timeout_ms", 3000),
new ChannelOption("grpc.http2.min_time_between_pings_ms", 5000),
};
// gRPC チャネル生成時の第3引数に IEnumerable でオプションを指定する
channel = new Channel(m_MagicOnionHost, 12345, ChannelCredentials.Insecure, options);
MagicOnion サーバ側
// 各種 keepalive 関連のオプションを設定する
List<ChannelOption> options = new List<ChannelOption> {
new ChannelOption("grpc.keepalive_time_ms", 2000),
new ChannelOption("grpc.keepalive_timeout_ms", 3000),
new ChannelOption("grpc.http2.min_time_between_pings_ms", 5000),
};
// `UseMagicOnion` 関数の第3引数に IEnumerable でオプションを指定する
await MagicOnionHost.CreateDefaultBuilder()
.UseMagicOnion(
new MagicOnionOptions(isReturnExceptionStackTraceInErrorDetail: true),
new ServerPort("0.0.0.0", 12345, ServerCredentials.Insecure),
options
).RunConsoleAsync();
これで MagicOnion に接続しているクライアントの接続が切れたら、
ある程度リアルタイムにネットワークの切断を検知することが可能になります。
具体的にはクライアント側の接続が切れてから MagicOnion サーバ側で のログ出力が確認できて、
OnDisconnected が呼ばれていることが確認出来ていれば、正常に設定されています
Keepalive watchdog fired. Closing transport.
おわりに
今回は切断検知のための gRPC チャネルの keepalive の設定を行いました
gRPC チャネルの keepalive 関連の設定項目は他にも色々あるようなので、
必要に応じてそれら項目を設定することで gRPC チャネルの接続周りの挙動をコントロール出来そうでした。
また今回の記事をきっかけに各種 gRPC オプションを眺めていたのですが、
普通に使ってる分には keepalive 周りの設定しか触ることは無さそうだなと感じました