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モジュールは、非常に柔軟性が高く、様々な操作に対応できるため、アプリケーション開発者はより「実現したいこと」に集中して実装することができるようになります。