# group\_sample

## group\_sample サンプル

### 概要

Group モジュールを使用して 2 人のユーザーがメッセージを送受信するサンプルコードです。\
Group モジュールの特徴については[こちらのページ](/diarkis-modules/group.md)を参照してください。

### ローカル環境でサーバーを起動する

サンプルで使用するサーバーを起動するためのチュートリアルを実施して、ローカル環境で Diarkis サーバーを起動します。

[1. Diarkis サーバーをローカル環境で起動する](/getting-started/tutorial/setup-local-server.md)

### サンプルの引数

サンプルの起動時には以下の３つのパラメータを指定してください。

`group_sample.exe serverAddr UID clientKey`

| 引数         | 説明                            |
| ---------- | ----------------------------- |
| serverAddr | Diarkis サーバのエンドポイントを指定してください  |
| UID        | 接続するユーザーの ID を任意の文字列で指定してください |
| clientKey  | クライアントキーを任意の文字列で指定してください      |

#### 起動例：

`group_sample.exe 192.168.1.123:7000 1111 AAAA`

### 起動方法

本サンプルは起動すると自動的に Group に接続してメッセージを送信します。 ほぼ同じタイミングで 2 つのサンプルを起動することで、それぞれのユーザーが送信したデータがお互いに受信する様子を確認することができます。

### サンプルコード説明

#### Group を使用する全体的な流れ

1. Diarkis ランタイムおよび Diarkis Module を初期化し、Diarkis サーバーへ接続します。\
   詳細については [Diarkis モジュール利用の全体的な流れ](https://help.diarkis.io/diarkis-client/samples/cpp/pages/r3yF3oFZnxAPw2prL13v#diarkis-モジュール利用の全体的な流れ) を参照してください。
2. セットアップ\
   Group モジュールを初期化します。

   ```
   diarkis = Diarkis::DiarkisAllocShared<DiarkisInterfaceBase>(uid);
   ...
   // Diarkis Module の Group のセットアップ
   diarkis->SetupGroup(false);
   ```
3. Group への参加

   ```
   // サーバに Group 参加を通知
   std::vector<uint8_t> joinMessage = {};
   diarkis->GetGroupBase()->SendRandomJoinGroup(60, joinMessage, 200, true);

   // Group に参加したか確認
   while (diarkis->GetGroupBase()->IsJoin() == false)
   {
       std::this_thread::sleep_for(std::chrono::milliseconds(100));
       continue;
   }
   ```
4. メッセージの送信\
   Group に参加完了後、Group に対してメッセージを送信します。\
   本サンプルでは `DiarkisGroupBase::SendBroadcastToGroup` を使用し、Group に参加しているメンバー全員にメッセージを送信します。

   ```
   std::vector<uint8_t> message = {};
   ...
   // message に作成したペイロードを送信します。
   // このメソッドを使用して送信したメッセージは DiarkisGroupBase::OnGroupMemberBroadcast で受け取ることができます。
   // Broadcast しているため、自分自身にもメッセージが返ってきます。
   diarkis->GetGroupBase()->SendBroadcastToGroup(message.data(), message.size(), false);
   ```
5. メッセージの受信\
   メッセージを受信すると `DiarkisGroupBase::OnGroupMemberBroadcast` が発火します。\
   コールバックでの処理をカスタマイズする方法については後述します。
6. 切断処理 Group から切断するには `DiarkisGroupBase::SendLeaveGroup` を使用します。

   ```
   std::vector<uint8_t> leaveMessage = {};
   diarkis->GetGroupBase()->SendLeaveGroup(groupId, leaveMessage);
   ```
7. 終了処理\
   詳細については [Diarkis モジュール利用の全体的な流れ](https://help.diarkis.io/diarkis-client/samples/cpp/pages/r3yF3oFZnxAPw2prL13v#diarkis-モジュール利用の全体的な流れ) を参照してください。

#### Group 関連処理のカスタマイズ

Group 関連の処理をカスタマイズする方法については [Diarkis Module のカスタマイズ](/diarkis-client/diarkis-module/how-to-customize-module.md) を参照してください。  サンプルでは以下のクラスでカスタム処理を実装しています。

ブロードキャストメッセージ受信時の処理

```
/**
* @~Japanese
* @brief Group モジュールで発生するイベントをアプリ側でカスタマイズするための実装
*/
class DiarkisGroupSample : public DiarkisGroupBase
{
public:
    DiarkisGroupSample() : DiarkisGroupBase() {}
    ~DiarkisGroupSample() override {}

    /**
    * @~japanese
    * @brief Group メンバーからのブロードキャストメッセージを受信した際に呼ばれるコールバック関数
    * @args[in] transportType 通信に使用されたプロトコルタイプ
    * @args[in] e ブロードキャストメッセージのペイロード
    */
    void OnGroupMemberBroadcast(DiarkisTransportType transportType, const DiarkisPayloadEventArgs& e) override
    {
        // sample_main 内で SendBroadcastToGroup に渡されたペイロードをパースしてデータを取得します。
        ...
```

カスタマイズしたクラスを `DiarkisInterfaceBase` で使用するには、 `DiarkisInterfaceBase` を継承してカスタマイズした `DiarkisGroupBase` クラスのインスタンスを作成するようにしてください。

```
/**
 * DiarkisInterface が内部で管理する各機能のモジュールをアプリ固有のものに置き換えるために DiarkisInterfaceBase を継承したクラスを実装します。
 */
class DiarkisInterfaceGroupSample : public DiarkisInterfaceBase
{
public:
    ...
    void SetupGroup(bool bRetry = false) override
    {
        if (groupBase_ == nullptr)
        {
            // You can use the customized Group class by instantiating it here.
            // アプリ側でカスタマイズしたクラスを作成します。
            groupBase_ = Diarkis::DiarkisAllocShared<DiarkisGroupSample>();
        }

        // Initialize Group instance and register callback functions.
        // Group クラスを初期化してコールバックイベントを登録
        DiarkisInterfaceBase::SetupGroup(bRetry);
        ...

```


---

# Agent Instructions: 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:

```
GET https://help.diarkis.io/diarkis-client/samples/cpp/group-sample.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
