6.7. デバッグ支援 - レイテンシエミュレーション

概要

PiaTransport  には、レイテンシエミュレーション機能が用意されています。レイテンシエミュレーション機能とは、通信において発生するレイテンシを意図的に長くすることで、ネットワーク環境が良好でない状況や、通信相手が遠距離に位置するような環境を擬似的に作り出す機能です。

内部動作

レイテンシエミュレーション機能が有効な状態では、PiaTransport の送受信スレッドはパケットを一時的にレイテンシエミュレーション用バッファに保存します。このとき、個々のパケットについて遅延時間を乱数で設定します。ここで決定された遅延時間が経過してからパケットを実際に送受信するので、パケットは通常より「遅れて」送受信されるようになります。

バッファ設定

前述したとおり、レイテンシエミュレーション機能にはパケットを一時的に保存するバッファが必要です。このバッファの個数は、アプリケーション側が transport::Transport::DebugSetting 構造体のメンバ変数で指定し、transport::Transport::SetDebugSetting() 関数を呼び出します。 通信量の多いアプリケーションや、最大遅延時間を長めに設定した場合では、それだけバッファが消費されますので、大きめのバッファを用意する必要があります。 もしバッファの大きさが不十分だと、バッファに保存できなかったパケットが捨てられ、あたかもパケロスが頻発しているかのような症状を示すことがあります。

注意:

transport::Transport::SetDebugSetting() を製品版 ROM で呼び出してはいけません。

 

コード 6-30. レイテンシエミュレーション用バッファ設定
// Transport::DebugSetting 構造体のメンバ変数にパラメータを設定していきます。
nn::pia::transport::Transport::DebugSetting debugSetting;
debugSetting.sendThreadLatencyEmulationPacketNum = 128; // バッファ1個あたり、約 1.5 KB のメモリを消費します。
debugSetting.receiveThreadLatencyEmulationPacketNum = 128; // バッファ1個あたり、約 1.5 KB のメモリを消費します。
debugSetting.isPacketLossEmulationEnabled = false; // ここではパケロスエミュレーション機能を無効に設定します。

// Transport::SetDebugSetting() でデバッグ機能を利用する場合は、Transport::CreateInstance() よりも先に呼び出す必要があります。
nn::pia::transport::Transport::SetDebugSetting(debugSetting);
 
// settingの各メンバ変数に適切な値をセット
nn::pia::transport::Transport::Setting setting;
...
...
 
// Transportクラスのインスタンスを作成
nn::pia::transport::Transport::GetInstance()->CreateInstance(setting);

レイテンシエミュレーション機能では、最小遅延時間と最大遅延時間を設定できます。ここで設定した範囲の遅延時間が、個々のパケット送受信のたびに一様乱数で決定されます。

コード 6-31. 最小/最大遅延時間の設定
nn::pia::transport::ThreadStreamManager* pMgr = nn::pia::transport::ThreadStreamManager::GetInstance();
PIA_SAMPLE_ASSERT(PIA_IS_VALID_POINTER(pMgr));
const int32_t SendMin = 0;
const int32_t SendMax = 500;
const int32_t ReceiveMin = 0;
const int32_t ReceiveMax = 500;
pMgr->SetSendThreadLatencyEmulation(SendMin, SendMax); // 送信レイテンシ設定(単位はミリ秒)
pMgr->SetReceiveThreadLatencyEmulation(ReceiveMin, ReceiveMax); // 受信レイテンシ設定(単位はミリ秒)

補足

ステーション間のレイテンシを計測するには、 transport::Station::GetRtt() などの API が利用できます。