本ページでは directmessage_simple
サンプルからコードの一部を紹介し Diarkis Module を利用する際の全体的な流れを説明します。
実際のサンプルのソースコードは samples\directmessage_simple\directmessage_simple.cpp
に配置されています。
Diarkis ランタイム・ライブラリおよび Diarkis Module の初期化
初めに Diarkis ランタイム・ライブラリ および Diarkis Module を初期化するために DiarkisInterfaceBase::DiarkisInit()
を呼び出します。
この処理はアプリケーション全体で最初に一度だけ実行する必要があります。
// Diarkis ランタイムの初期化処理
// Diarkis の機能を使用する前にアプリケーション全体で一度だけ呼び出す必要があります。
// 本サンプルではファイルにログを出力する設定でランタイムを初期化します。
DiarkisInterface::DiarkisInit(uid, LogOutType::FILE_OUT, true, nullptr);
DiarkisInterfaceBase インスタンスの作成
次に Diarkis サーバーに接続して Diarkis の各種機能を使用するために DiarkisInterfaceBase
を継承したクラスのインスタンスを作成します。
この時 Diarkis サーバーへ接続する際に使用する UID(User ID)
を渡します。
// Diarkis のすべての機能にアクセスするために DiarkisInterface を継承したクラスを作成します。
diarkis = Diarkis::DiarkisAllocShared<DiarkisInterfaceDirectMessageSimple>(uid);
低レベル通信レイヤーの初期化
DiarkisInterfaceBase
のインスタンス作成後、Diarkis サーバーとの通信に使用する TCP/UDP 通信をセットアップします。
Diarkis サーバーへの接続情報取得
次に Diarkis サーバーへ接続するための情報を取得します。
(TODO) クライアントキーやサーバー・タイプなどの説明を軽くしたい。
付属サンプルではサンプル実装として Diarkis クラスタ内の HTTP サーバーから接続情報を取得するパターンと API サーバー(外部サーバー)経由で接続情報を取得する2パターンが実装されています。
Diarkis クラスター内の HTTP サーバーから接続情報を取得するパターン
DiarkisInterfaceBase::GetEndpoint()
を使用して接続情報を取得します。
取得した接続情報は DiarkisInterfaceBase
内に自動的に保存され接続する時に使用されます。
#if API_AUTH == 0
// Diarkis クラスタ内の HTTP サーバーへアクセスして、DirectMessage 通信で使用するサーバーのエンドポイントを取得します。
// 通信に使用する方法に応じて適切なサーバー・タイプを指定してサーバーからエンドポイントを取得する必要があります。
if (diarkis->GetEndpoint(host.c_str(), clientKey.c_str(), serverType.c_str(), endpoint, 256) == false)
{
DiarkisUtils::Print("Failed to get %s endpoint: host=%s uid=%s clientKey=%s", serverType.c_str(), host.c_str(), uid.c_str(), clientKey.c_str());
DiarkisInterface::DiarkisDestroy();
return 1;
}
DiarkisUtils::Print("Endpoint: %s", endpoint);
DiarkisUtils::Print("UID : %s\n", uid.c_str());
#endif // API_AUTH
また、サンプルでは使用していませんが
DiarkisInterfaceBase::RequestEndpointAsync()
DiarkisInterfaceBase::GetEndpointAsyncStatus()
DiarkisInterfaceBase::GetAsyncEndpointResult()
を使用して、非同期処理でエンドポイント情報を取得することも可能です。
API サーバー(外部サーバー)経由で接続情報を取得するパターン
API サーバー(外部サーバー)など、何らかの方法で取得した接続情報を AuthInfo
へ保存し、実際の接続時にこの情報を渡して接続処理を行います。
#if API_AUTH
struct AuthInfo auth;
//diarkis->GetAuthInfo(&auth);
// 以下は API サーバー(外部サーバー)経由で取得した UDP 接続情報を使用して UDP サーバーに接続するためのサンプル・コードです。
// GetEndpoint() を呼ばない場合は、APIサーバー経由 で取得した接続情報をセットする必要があります。
// 以下はあくまでサンプルの接続情報になりますので、このままのコードでは UDP サーバーに接続することはできません。
std::string endpointString = "192.168.10.5:7100";
std::string sidString = "a19c5dbb52de43e4a1fad47e5df166e0";
std::string keyString = "495c0ca446704cb3ab37a8bd986c57a1";
std::string ivString = "5b0ca9eb9de34df0b333eccd878d524f";
std::string mackeyString = "88253f5c994a45bc9d9a6eb9ed502075";
// 以下が、endpoint と auth 構造体の sid, cred.key, cred.iv, cred.mac をセットする際のサンプル・コードになります。
strcpy(endpoint, endpointString.c_str());
HexadecimalStringToByteArray(sidString.c_str(), auth.sid, DIARKIS_AUTHKEY_LEN);
HexadecimalStringToByteArray(keyString.c_str(), auth.cred.key, DIARKIS_AUTHKEY_LEN);
HexadecimalStringToByteArray(ivString.c_str(), auth.cred.iv, DIARKIS_AUTHKEY_LEN);
HexadecimalStringToByteArray(mackeyString.c_str(), auth.cred.mac, DIARKIS_AUTHKEY_LEN);
#endif // API_AUTH
Diarkis サーバーへ接続
外部から接続情報を取得した場合はこのタイミングで取得した情報を渡します。
また、接続処理を実行後、実際に接続が完了するまで時間がかかることがあるため接続状態を定期的にチェックして接続が完了したかどうかを確認します。
// HTTP アクセスで取得したエンドポイントへ接続して Diarkis サーバーとの通信を確立します。
// 本サンプルでは TCP/UDP ソケットを使用して Diarkis サーバーへ接続します。
bool connectResult = false;
#if API_AUTH == 0
connectResult = diarkis->ConnectUdp(endpoint);
#else
connectResult = diarkis->ConnectUdp(endpoint, serverType.c_str(), &auth);
#endif
// DiarkisInterface::ConnectUdp/Tcp() の呼び出しで接続処理は開始していますが、実際に接続が完了するまでは時間が少し時間がかかることがあります。
// 確実に接続出来たことを確認するため、TCP/UDP 接続の状態をチェックする。
while (!diarkis->GetUdpBase()->IsConnected())
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
モジュール毎の初期化
Diarkis サーバーへの接続が完了した後は使用したい各モジュールのセットアップを行い、アプリケーションが必要な通信処理を行います。
// DiarkisInterface 内で管理されている DirectMessage モジュールを初期化します。
// DirectMessage モジュールのインスタンスを確保して、通信に使用する TCP/UDP モジュールと関連付けます。
// 以降、DirectMessage モジュールのポインターを DiarkisInterface から取得して DirectMessage の機能にアクセスします。
diarkis->SetupDirectMessage();
Diarkis サーバーから切断
DiarkisInterfaceBase::Disconnect()
を呼び出すことで Diarkis サーバーからの切断処理が開始されます。
接続時と同様に実際に切断が完了するまでは時間がかかることがあるため、切断処理を実行後に接続状態をチェックして切断が完了したかどうかを確認します。
// Diarkis サーバーとの接続を切断
diarkis->Disconnect();
// DiarkisInterface::Disconnect() の呼び出しで切断処理は開始しているが、実際に切断が完了するまでは時間が少し時間がかかることがある。
// 確実に切断してから終了処理に移行するため、TCP/UDP 接続の状態をチェックする。
while (diarkis->GetUdpBase()->IsConnected() == true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
使用済みインスタンスの開放
Diarkis サーバーからの切断が完了し DiarkisInterfaceBase
が必要なくなったためインスタンスを開放します。
終了処理
アプリケーションの終了時に DiarkisInterfaceBase::DiarkisDestroy()
を呼び出して Diarkis 全体の終了処理を行います。 この処理は DiarkisInterfaceBase::DiarkisInit()
と対になっていて、DiarkisInit
同様にアプリケーションのライフサイクル全体で一度だけ呼び出してください。
// Diarkis ランタイムの終了処理
// Diarkis を使用し終わったらアプリケーション終了時などに一度だけ DiarkisInterface::DiarkisDestroy() を呼び出します。
DiarkisInterface::DiarkisDestroy();