株式会社Diarkis

トップ > 技術ブログ > Diarkis Roomモジュールのご紹介

Diarkis Roomモジュールのご紹介

DiarkisのRoomモジュールを利用することで、仮想的に作成されたルームを共有して、リモートクライアント間でメッセージを交換できます。
またRoomモジュールは、ブロードキャストやメッセージ機能を通じてRPCコマンドを交換するためのRPCブローカーとしても機能します。

Roomモジュールのセットアップ

Roomモジュールを利用するためには、ネットワーククライアントインスタンスを渡す必要があります。
以降で、Diarkis C#クライアントによるRoomモジュールの使い方を解説します。
なおRoomモジュールは、使用できる通信プロトコル(TCP/UDP/RUDP)に制限はありません。

UDPクライアントを使用する

Diarkis.Udp udp = new Diarkis.Udp();
Diarkis.Modules.Room room = new Diarkis.Modules.Room();
// This is how you pass a UDP client instance
room.SetupAsUdp(udp);

TCPクライアントを使用する

Diarkis.Tcp tcp = new Diarkis.Tcp();
Diarkis.Modules.Room room = new Diarkis.Modules.Room();
// This is how you pass a TCP client instance
room.SetupAsTcp(tcp);

Roomの作り方

Roomモジュールは、メンバー数上限を指定することができます。
以下の例では、メンバー上限を10としてRoomを作成します。

// Maximum number of members for this room
int maxMembers = 10;
// If true, the room will not be discard when it is empty
bool allowEmpty = false;
// If true, the creator will automatically join the room created
bool join = true;
// TTL of the room in seconds when it is empty (this is only effective when allowEmpty=true)
int ttl = 60;
// Broadcast message buffering interval in milliseconds to lessen server stress
int interval = 200;

room.OnCreate += HandleOnRoomCreate;

// Creates a new room and raises OnCreate event 
room.Create(maxMembers, allowEmpty, join, ttl, interval);

private void HandleOnRoomCreate(bool success, string roomID, uint createdTime)
{
    // success = false means we failed to create a new room
    // createdTime is the timestamp of the room creation
}

Roomに参加する方法

Room作成時に取得したRoom IDを外部に保存したものか、マッチメイキング機能を使用してRoom IDを共有することで、Roomに参加することができます。
Roomに参加すると、参加したクライアントではOnJoinが発火し、Roomに参加している他のメンバーのクライアントではOnMemberJoin(後述)が発火します。
Roomに参加する際には、先述の通りすでに参加しているリモートクライアントで通知メソッドが発火しますので、誰が参加したかなどに応じた処理を行いたい場合はmessageに識別情報などを含めることを推奨します。

byte[] message = Encoding.UTF8.GetBytes("Hello World"); 
// This message will be sent to the other members when you join the room successfully. Other members will receive the message via OnMemberJoin event
room.Join(roomID, message);

UDPクライアントが使用されている場合でも、この処理ではRUDPメッセージとして送信されます。

新たに参加したメンバーを検知する

Roomに新たなメンバーが参加すると、OnMemberJoinイベントが発火します。
以下は、発火したイベントを処理する例です。

room.OnMemberJoin += HandleRoomOnMemberJoin;

private void HandleOnRoomMemberJoin(byte[] message)
{
   // message is the message byte array that the new member sent with room.Join()
}

Roomからの退出方法

Roomから退出(room.Leave)すると、クライアントではOnLeaveが発火し、Roomに参加中の他のメンバーのリモートクライアントではOnMemberLeaveが発火します。
他のメンバーは、誰がRoomを退出したかに応じた処理を行いたい場合は、messageに識別情報などを含めることを推奨します。

byte[] message = Encoding.UTF8.GetBytes("Bye World");
// This message will be sent to the other members when you leave the room successfully. Other members will receive the message via OnMemberLeave event
room.Leave(room.GetRoomID(), message);

UDPクライアントが使用されている場合でも、この処理ではRUDPメッセージとして送信されます。

退出したメンバーを検知する

Roomに参加中のメンバーが退出したときには、OnMemberLeaveイベントが発火します。
以下は、発火したイベントを処理する例です。

room.OnMemberLeave += HandleRoomOnMemberLeave;

private void HandleRoomOnRoomMemberLeave(byte[] message)
{
    // message is the byte array the member left sent with room.Leave()
}

ランダムにRoom参加したり、Roomが空いていない場合に新たなRoomを作成する

単にクライアントがランダムにRoomに参加したり、Roomを作成したりしたい場合は、このメソッドを使います。このメソッドで発生するイベントは、OnJoin/OnMemberJoinまたはOnCreateと同じです。 UDPクライアントを使用している場合、メッセージはRUDPとして送信されます。

// Maximum number of members for this room
int maxMembers = 10;
// TTL of the room in seconds when it is empty (this is only effective when allowEmpty=true)
int ttl = 60;
// This message will be sent to the other members when you join the room successfully. Other members will receive the message via OnMemberJoin event
byte[] message = Encoding.UTF8.GetBytes("Hello World");
// Broadcast message buffering interval in milliseconds to lessen server stress
int interval = 200;
room.JoinRandom(maxMembers, ttl, message, interval);

Roomの全メンバーにメッセージをブロードキャストする方法

ブロードキャストメソッドは、自分を含むルームの全メンバーにメッセージを送信します。このメッセージはOnMemberBroadcastによって受信されます。メッセージには送信者のユーザーIDなどを含めることをお勧めします。これにより、受信者は誰がメッセージを送信したかを検知し、それに応じた行動をとることができます。

byte[] message = Encoding.UTF8.GetBytes("Hello World");
// For UDP, if set to true, broadcast message will be sent as an RUDP packet
bool reliable = false;
room.BroadcastTo(room.GetRoomID(), message, reliable);

ブロードキャストメッセージの受信方法

他のメンバーがブロードキャストメッセージを送信すると、OnMemberBroadcastイベントが発生します。以下に、このイベントの処理方法の例を示します。

room.OnMemberBroadcast += HandleOnRoomMemberBroadcast;

private voidd HandleOnRoomMemberBroadcast(byte[] message)
{
    // Do something great with the message
}

Roomの特定のメンバーにメッセージを送信する方法

Roomの全メンバーではなく、選択したメンバーにメッセージを送信することができます。このメッセージはOnMemberMessageによって配信されます。メッセージには送信者のユーザーIDなどを含めることをお勧めします。これにより、受信者は誰がメッセージを送信したかを検知し、それに応じた行動をとることができます。

// For UDP, if set to true, broadcast message will be sent as an RUDP packet
byte[] message = Encoding.UTF8.GetBytes("Hellow World");
bool reliable = false;
room.MessageTo(room.GetRoomID(), message, reliable);

Roomのプロパティを取得する方法

プロパティ名を指定することで、自分がいるRoomのプロパティを取得することができます。取得したプロパティを読み出すには、OnGetPropertiesをリッスンする必要があります。すべてのプロパティはバイト配列です。 UDPクライアントを使用した場合、メッセージはRUDPとして送信されます。

List<string> propertyNames = new List<string>();
propertyNames.Add("roomName");
propertyNames.Add("roomNo");
room.GetProperties(room.GetRoomID(), propertyNames);

Roomのプロパティを更新する方法

自分がいるRoomのプロパティを更新することができます。すべてのプロパティ値はバイト配列でなければなりません。UpdatePropertiesをコールすると、OnUpdatePropertiesが発生します。 UDPクライアントを使用している場合、メッセージはRUDPとして送信されます。

Dictionary<string, byte[]> props = new Dictionary<string, byte[]>();
props["roomName"] = Encoding.UTF8.GetBytes("Sample Room");
props["roomNo"] = BitConverter.GetBytes(123);
room.UpdateProperties(room.GetRoomID(), props);

Roomの数値プロパティを同期させる方法

Roomのプロパティを使用することで、数値プロパティを共有・同期することができます。
以下の例では、数値化されたRoomプロパティを参加メンバー間で管理・同期する方法を説明します。

Roomの数値プロパティを同期させる設定

以下の例では、イベントリスナーを設定して、数値プロパティ値をRoomの全メンバーに同期させる方法を説明しています。

// This event is raised when a numeric room property value changes
room.OnIncrPropertySync += OnDiarkisRoomIncrPropertySync;

private void OnDiarkisRoomIncrPropertySync(long value)
{

        // Update UI and do some cool things here
}

Roomの数値プロパティを初期化する方法

通常、Roomを作成したユーザークライアントは、数値プロパティを初期化します。

// We do not need to synchronize with other members assuming there is nobody yet
bool sync = false; 
// This initializes a numeric room property named HP and its value will be 1000
room.IncrProperty("HP", 1000, sync)

Roomの数値プロパティを同期的に更新する方法

Roomの数値プロパティをインクリメントまたはデクリメントし、Roomの他のメンバーと自動同期させることができます。

// This event is raised when the update is synchronized from another member
room.OnIncrPropertySync += OnDiarkisRoomIncrPropertySync;

private void OnDiarkisRoomIncrPropertySync(long updatedValue)
{
        // Update UI and do something awesome
}

// This is how you update a numeric room property
// This will be subtracting HP by 100
// synchronize = true means auto-synchronization with other members
bool  synchronize = true;
room.IncrProperty("HP", -100, synchronize);

Roomの数値プロパティを新規メンバーに同期させる方法

新しいメンバーがRoomに参加するときには、そのクライアントは、数値プロパティの現在の値を取得する必要があります。

// We retrieve "HP" after we join a room
room.OnJoin += OnDiarkisRoomJoin;

private void OnDiarkisRoomJoin(bool success, uint createdTime)
{
        if (!success)
        {
                // Handle error...
                return;
        }
        // Retrieve "HP"
        List<string> propertyNames = new List<string>();
        propertyNames.Add("HP");
        // This raises OnGetProperties event and that is how you retrieve the property data
        room.GetProperties(room.GetRoomID(), propertyNames);
}

// This is how to retrieve "HP" from the server
room.OnGetProperties += OnDiarkisRoomGetProperties;

private void OnDiarkisRoomGetProperties(bool success, Dictionary<string, byte[]>properties)
{
        if (!success)
        {
                // Handle error...
                return;
        }
        if (!properties.ContaionsKey("HP"))
        {
                // "HP" is missing...
                return;
        }
        // Update local "HP"
        Array.Reverse(properties["HP"]); // Big Endian
        _hp = BitConverter.ToInt64(msg.Value, 0);
}

他のメンバーのIDとオーナーのIDを取得する方法

オーナーIDとともに、メンバーIDの一覧を取得することができます。

room.OnGetMemberIDs += OnDiarkisRoomGetMemberIDs;

private void OnDiarkisRoomGetMemberIDs(bool success, string ownerID, string[] memberIDs)
{
	// Do something great here!
}

// This will raise OnGetMemberIDs event
room.GetMemberIDs();

おわりに

Roomの概念は、リアルタイムアプリケーションの最も基本的な概念の1つです。
DiarkisのRoomモジュールは、非常に柔軟性が高く、様々な操作に対応できるため、アプリケーション開発者はより「実現したいこと」に集中して実装することができるようになります。

大規模マルチユーザー間通信をDiarkisが実現します

お問い合わせ
このエントリーをはてなブックマークに追加

この記事もおすすめ

Diarkisをもっと知りたい、採用を検討したい場合は以下よりお問い合わせください

お問い合わせ 資料請求
PAGE TOP