さて、Unionの醍醐味は、他のユーザと情報を共有するところにあると考えます。 前回みたように、情報の共有化にはいくつかの方法があることが分かりました。今回は、その手段の使いどころ整理してみます。UnionのバージョンはUnion alpha3を使用します。
どんな手段があるのか
情報の共有化は大きく分けて、Attributeによる共有とMessageによる共有に分けることが出来ます。
Attributeによる共有は、RoomのAttributeとClientのAtrributeがあります。
Messageによる共有は、Room(RoomManager) APIによるMessageとClient(ClientManager) APIによるMessageがあります。また、Union ServerからMessageを送信することも可能です。
まとめると以下のようになります。
- Attributeによる共有
- Room Attribute
- Client Attribute
- Messageによる共有
- Server APIによるMessage
- RoomManager APIによるMessage
- Room APIによるMessage
- ClientManager APIによるMessage
- Client APIによるMessage
- Union ServerからのMessage
各手段の特徴と使いどころ
次に先ほどの、情報の共有化手段の特徴と使いどころを考えて見ます。
Attributeによる共有
Room Attribute
Roomに対する属性の変更は、Roomに接続(join, observe)しているClientすべてに通知されます。よって、Roomに接続(join, observe)しているすべてのClientで共有したい情報はRoom Attributeを使います。ただし、ClientはRoom Attributeの通知を拒否する事も出来ます。
例えば、チャットを開催するRoomを考えます。チャット部屋の背景の色は参加者全員で共有すべき情報なので、Room Attributeを使うと良いでしょう。また、チャット内の話題や、発言回数、ビジュアル的な背景などの設定もRoom Attributeに適しています。
このRoom Attributeは、途中からRoomに接続したClientに対しては最新の情報が共有されます。たとえば、以下のようなシチュエーションが考えられます。
- Room Attribute backgroundはred
- Client Aがbackgroundをorangeに変更し、Client AとClient BにRoom Attributeのbackgroundがorangeへ更新されたことが通知される。
- Client Bがbackgroundをblueに変更し、Client AとClient BにRoom Attributeのbackgroundがblueへ更新されたことが通知される。
- Client CがRoomにjoinし、Room Attributeのbackgroundがblueであることを確認する。
図解すると以下のようになります。
このとき、Client CはRoom Attributeが以前はred, orangeであった事を知りえません。
このように、画面内の最新情報を共有する際にRoom Attributeが適している事が多いです。他にも色々考えられます。
- ボードゲームのどのボードに何が置かれているかという情報
- お絵描きチャットのキャンバスの情報
- 陣取りゲームでどの陣が誰の陣であるかという情報
Room Attributeの永続化
また、Roomに設定されたRoom Attributeは、永続化することで次回の接続にも前回設定したRoom AttributeをUnion Serverへ保存しておく事が可能です。
ただ、現地点では、サーバ再起動時に永続化データは消えてしまうようです。
Client Attribute
Clientの持つ属性を他のClientと共有したいとき、Client Attributeを使います。Room Attributeとの違いとして、Client Attributeにはスコープという概念があります。
スコープは以下のようになります。
- グローバル
- 特定のRoom(Room IDで指定)
グローバルスコープに指定したClient Attributeの更新は、該当するClientが接続(join, observe)している全Room、Clientへ通知されます。特定のRoomをスコープとするClient Attributeの更新は、特定のRoomとそのRoomに接続(join, observe)しているClientへ通知されます。
チャットRoomとゲームRoomが存在するアプリケーションの場合、どちらのRoomにおいてもユーザーのニックネームやキャラクターカラーという情報は必要となります。ゲームRoomでは現在のゲーム上のカーソルの位置はゲームRoomだけで必要なClient Attributeとなるでしょう。
上記の図で、両方のRoomに共通するニックネームとキャラの色をグローバルスコープ。ゲームRoomでのユーザのカーソル位置はゲームRoomスコープに設定します。 Room Attributeと同様に、途中からRoomに接続したClientに対しては最新の情報が共有されます。
Client Attributeの永続化
また、Clientに設定されたClient Attributeは、永続化することで次回の接続にも前回設定したClient AttributeをUnion Serverへ保存しておく事が可能です。
ただ、こちらはUnion alpha3では永続化したClientデータをひもづける手段が提供されていなようなので未対応のようです。もし、情報をお持ちの方がいらっしゃいましたらご教授いただけるとうれしいです。
Messageによる共有
Attributeは最新の情報が共有されるため、Clientはその場に居合わせなくても最新の情報は取得できます。それに対して、Messageは、その場に居合わせた人だけが受け取れる共有情報です。
現実の例として、AさんとBさんが会話をしているとき、途中でやってきたCさんは今までAさんとBさんが話していた内容を知ることは出来ません。
ただ、CさんはAさんかBさんに、今まで何を話していたのかを聞くことによって、今までの会話の内容を知ることが出来ます。AさんとBさんが会話をしながら、すべての記録をノートに書いていれば、後から来たCさんはそれを見ることで今までの会話の内容を知ることが出来ます。
同じような事をReactorで実現しようとすると、以下のような手順になります。
- ClientがMessageを送信する
- Messageを受け取ったClientはその内容を配列に保存する
- 途中から新しいClientがRoomに接続する
- 新しいClientは、一番最初から要るClientに今までのMessageの結果の送信を要求するMessageを送信する
- 一番最初から要るClientは、新しいClientへ今までのMessageの結果を送信する
Server APIによるMessage
Serverに接続する全Client、または特定のClient Attributeを持つClientへ共有したい情報を送信する際に利用します。
RoomManager APIによるMessage
指定した複数のRoomに接続する全Client、または特定のClient Attributeを持つClientへ共有したい情報を送信する際に利用します。
Room APIによるMessage
Roomに接続する全Client、または特定のClient Attributeを持つClientへ共有したい情報を送信する際に利用します。
ClientManager APIよるMessage
特定のClientに対して共有したい情報を送信する際に利用します。チャットRoom内で秘密のメッセージ交換などの利用します。
Client APIよるMessage
指定した複数のClientに対して共有したい情報を送信する際に利用します。チャットRoom内で秘密のメッセージ交換などの利用します。
Union ServerからのMessage
Union Serverでは、Server Module、Room ModuleといったModuleを定義することによって、各種イベント発生をトリガーとした、処理や、定期的な処理を作成する事が出来ます。
それらのModuleからMessageを送信することによって、Union ServerはRoomやClientに対してMessageを送信する事が出来ます。ReactorではRoomやClientのAPIを利用したMessageと同様に、Union ServerからのMessageを受け取る事が可能です。 Union ServerのModuleを作成方法を紹介する際に具体的な実装方法を見て行きます。
情報の共有化のまとめ
ここまでの情報の共有化についてまとめてみます。
発信元 | API | 方法 | 新たなユーザへの情報提供 | 情報の永続化 |
---|---|---|---|---|
Reactor | Room.setAttribute() | Room Attribute | 最新の情報 | 可能だがサーバ再起動で消える |
Reactor | Client.setAttribute() | Client Attribute | 最新の情報 | 可能な予定だが未対応 |
Reactor | Server.sendMessage(); | Server APIによるMessage | 次回以降の情報 | 不可 |
Reactor | RoomManager.sendMessage(); | RoomManager APIによるMessage | 次回以降の情報 | 不可 |
Reactor | RoomManager.sendMessage(); | Room APIによるMessage | 次回以降の情報 | 不可 |
Reactor | ClientManager.sendMessage(); | ClientManager APIによるMessage | 次回以降の情報 | 不可 |
Reactor | Client.sendMessage() | Client APIによるMessage | 次回以降の情報 | 不可 |
Union Server | Client.sendMessage(), Room.sendMessage(); | Union ServerからのMessage | 次回以降の情報 | 不可 |
以降、今回の情報共有化とは直接関係するわけではありませんが、Module Messageについて紹介します。Union Serverにログを保存したり、外部APIにログを保存する際などに使えるので、情報の共有化と関係があると考え、今回紹介します。
Module Message
Module Messageでは、Union Serverに対してMessageを送信します。送信したMessageの内容をUnion Server側で以下のような処理が可能です。
- チャットのログをDBに保存してからUnion ServerからのMessageでRoom, Clientへ通知する
- 受け取った情報を整形(チャット内の禁止用語を伏せ字にするなど)して、Union ServerからのMessageでRoom, Clientへ通知する
- Web APIを使ってtwitterへ投稿してからUnion ServerからのMessageでRoom, Clientへ通知する
このような処理を実装するためにはUnion Server側にServer ModuleもしくはRoom Moduleを設置する必要があります。Server ModuleとRoom ModuleはJAVA言語で作成することが出来ます。
もちろん、Module Message側でUnion ServerのMessageを使わない事も出来ます。Message Moduleに関しては、Union ServerのServer Module, Room Moduleの作成方法を紹介する回で詳しくみて行こうと思います。
次回は、ReactorのRoomEventやClientEventをみながら、情報の共有化を実装する方法を紹介しようと思います。