> For the complete documentation index, see [llms.txt](https://help.diarkis.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.diarkis.io/diarkis-client/diarkis-module/how-to-init-deinit.md).

# Diarkis Module の初期化と終了

本ページでは `directmessage_simple` サンプルからコードの一部を紹介し **Diarkis Module** を利用する際の全体的な流れを説明します。\
実際のサンプルのソースコードは `samples\directmessage_simple\directmessage_simple.cpp` に配置されています。

## Diarkis ランタイム・ライブラリおよび Diarkis Module の初期化

初めに **Diarkis ランタイム・ライブラリ** および **Diarkis Module** を初期化するために `DiarkisInterfaceBase::DiarkisInit()` を呼び出します。\
この処理はアプリケーション全体で最初に一度だけ実行する必要があります。

```cpp
    // Diarkis ランタイムの初期化処理
    // Diarkis の機能を使用する前にアプリケーション全体で一度だけ呼び出す必要があります。
    // 本サンプルではファイルにログを出力する設定でランタイムを初期化します。
    DiarkisInterface::DiarkisInit(uid, LogOutType::FILE_OUT, true, nullptr);
```

## DiarkisInterfaceBase インスタンスの作成

次に Diarkis サーバーに接続して Diarkis の各種機能を使用するために `DiarkisInterfaceBase` を継承したクラスのインスタンスを作成します。\
この時 Diarkis サーバーへ接続する際に使用する `UID(User ID)` を渡します。

```cpp
    // Diarkis のすべての機能にアクセスするために DiarkisInterface を継承したクラスを作成します。
    diarkis = Diarkis::DiarkisAllocShared<DiarkisInterfaceDirectMessageSimple>(uid);
```

## 低レベル通信レイヤーの初期化

`DiarkisInterfaceBase` のインスタンス作成後、Diarkis サーバーとの通信に使用する TCP/UDP 通信をセットアップします。

```cpp
    diarkis->SetupUdp();
```

## Diarkis サーバーへの接続情報取得

次に Diarkis サーバーへ接続するための情報を取得します。\
付属サンプルではサンプル実装として Diarkis クラスタ内の HTTP サーバーから接続情報を取得するパターンと API サーバー（外部サーバー）経由で接続情報を取得する2パターンが実装されています。

**Diarkis クラスター内の HTTP サーバーから接続情報を取得するパターン**

`DiarkisInterfaceBase::GetEndpoint()` を使用して接続情報を取得します。\
取得した接続情報は `DiarkisInterfaceBase` 内に自動的に保存され接続する時に使用されます。

```cpp
#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` へ保存し、実際の接続時にこの情報を渡して接続処理を行います。

```cpp
#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 サーバーへ接続

外部から接続情報を取得した場合はこのタイミングで取得した情報を渡します。\
また、接続処理を実行後、実際に接続が完了するまで時間がかかることがあるため接続状態を定期的にチェックして接続が完了したかどうかを確認します。

```cpp
    // 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 サーバーへの接続が完了した後は使用したい各モジュールのセットアップを行い、アプリケーションが必要な通信処理を行います。

```cpp
    // DiarkisInterface 内で管理されている DirectMessage モジュールを初期化します。
    // DirectMessage モジュールのインスタンスを確保して、通信に使用する TCP/UDP モジュールと関連付けます。
    // 以降、DirectMessage モジュールのポインターを DiarkisInterface から取得して DirectMessage の機能にアクセスします。
    diarkis->SetupDirectMessage();
```

## Diarkis サーバーから切断

`DiarkisInterfaceBase::Disconnect()` を呼び出すことで Diarkis サーバーからの切断処理が開始されます。\
接続時と同様に実際に切断が完了するまでは時間がかかることがあるため、切断処理を実行後に接続状態をチェックして切断が完了したかどうかを確認します。

```cpp
    // Diarkis サーバーとの接続を切断
    diarkis->Disconnect();

    // DiarkisInterface::Disconnect() の呼び出しで切断処理は開始しているが、実際に切断が完了するまでは時間が少し時間がかかることがある。
    // 確実に切断してから終了処理に移行するため、TCP/UDP 接続の状態をチェックする。
    while (diarkis->GetUdpBase()->IsConnected() == true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
```

## 使用済みインスタンスの開放

Diarkis サーバーからの切断が完了し `DiarkisInterfaceBase` が必要なくなったためインスタンスを開放します。

```cpp
    diarkis = nullptr;
```

## 終了処理

アプリケーションの終了時に `DiarkisInterfaceBase::DiarkisDestroy()` を呼び出して Diarkis 全体の終了処理を行います。 この処理は `DiarkisInterfaceBase::DiarkisInit()` と対になっていて、`DiarkisInit` 同様にアプリケーションのライフサイクル全体で一度だけ呼び出してください。

```cpp
    // Diarkis ランタイムの終了処理
    // Diarkis を使用し終わったらアプリケーション終了時などに一度だけ DiarkisInterface::DiarkisDestroy() を呼び出します。
    DiarkisInterface::DiarkisDestroy();
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.diarkis.io/diarkis-client/diarkis-module/how-to-init-deinit.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
