MUN のネットワークシーケンスについて

目次

  概要
  ネットワークシーケンス図
  シーケンス1:サーバ起動後の初期設定
  シーケンス2:サーバ起動中の更新処理
  シーケンス3:MUN クライアントから mun_resolver サーバへの接続
  シーケンス4:MUN クライアントから mun_proxy サーバへの接続
  シーケンス5:MUN クライアント認証処理
  シーケンス6:ロビーの作成
  シーケンス7:ロビーへの入室
  シーケンス8:プレイヤーの検索
  シーケンス9:ルームの作成
  シーケンス10:ルームへの入室
  シーケンス11:ルーム内情報の更新処理
  シーケンス12:ルームからの退室


概要

MUN 2.0 以降の「MUN クライアント」と「MUN サーバ」間のデータフローについて

  このページでは、MUN 2.0 以降のクライアントとサーバ間にて、どういった手順で情報を授受しているのかについて、
  実際のコードと併せて説明いたします。


ネットワークシーケンス図

MUN 2.2.1 リリース段階でのネットワークシーケンス図

  MUN 2.2.1 のリリース段階では、ネットワークシーケンスは以下の通りです。
MUN のネットワークシーケンスは下図の通りです。
画像をクリックすることで、等倍の拡大図を開くことができます。
  シーケンス図中にて触れている各種手続きについては、次項より説明します。


シーケンス1:サーバ起動後の初期設定

MUN サーバプロセスが起動直後の初動処理

  MUN サーバプロセスを起動させた直後、各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN プロセスを mun_master → mun_resolver → mun_proxy の順に起動させた直後、
mun_proxy のサーバプロセスが、mun_master のサーバプロセスに接続します。
上記の処理を受けて、mun_master のサーバプロセスが mun_proxy のサーバプロセスに、接続応答を返します。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされる関数です。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされるメソッドです。
1. とほぼ同時に実行されますが、mun_proxy のサーバプロセスが、mun_resolver のサーバプロセスに接続します。
上記の処理を受けて、mun_resolver のサーバプロセスが mun_proxy のサーバプロセスに、接続応答を返します。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされる関数です。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされるメソッドです。
上記の処理を受けて、mun_proxy と mun_resolver の双方のサーバプロセスの接続が確立した時点で、
「mun_proxy がMUN クライアントを待ち受けしているIPアドレスとポート番号」について、mun_resolver に通知します。
ここで、MunProxySessionToResolverServer::Send_ProxyResolver_SetTcpAddress() 関数、
および、MunProxySessionToResolverServer::Send_ProxyResolver_SetUdpAddress() 関数を呼び出し、
mun_resolver に対し、「mun_proxy 側が MUN クライアントを待ち受けしている TCP/UDP のアドレス情報」を送信しています
ここで、MunProxySessionToResolverServer.Send_ProxyResolver_SetTcpAddress() メソッド、
および、MunProxySessionToResolverServer.Send_ProxyResolver_SetUdpAddress() メソッドを呼び出し、
mun_resolver に対し、「mun_proxy 側が MUN クライアントを待ち受けしている TCP/UDP のアドレス情報」を送信しています
mun_room のサーバプロセスを起動させた直後、mun_room のサーバプロセスが、mun_master のサーバプロセスに接続します。
上記の処理を受けて、mun_master のサーバプロセスが mun_room のサーバプロセスに、接続応答を返します。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされる関数です。
接続応答自体は MRS ライブラリ内部で実行しています。
下記に示すのは、その接続応答と同時にコールバックされるメソッドです。
上記の処理を受けて、mun_room と mun_master の双方のサーバプロセスの接続が確立した時点で、
「mun_room が MUN クライアントを待ち受けしているIPアドレスとポート番号」について、mun_master に通知します。
ここで、MunRoomSessionToMasterServer::Send_RoomMaster_SetAddress() 関数を呼び出し、
mun_master に対し、「mun_room 側が MUN クライアントを待ち受けしている TCP/UDP のアドレス情報」を送信します。
ここで、MunRoomSessionToMasterServer.Send_RoomMaster_SetAddress() メソッドを呼び出し、
mun_master に対し、「mun_room 側が MUN クライアントを待ち受けしている TCP/UDP のアドレス情報」を送信します。


シーケンス2:サーバ起動中の更新処理

MUN サーバプロセスが稼働中にリアルタイムで実行される処理

  MUN サーバプロセスを稼働中、各サーバプロセスで行われる以下の工程について、順に説明いたします。
mun_proxy サーバプロセスが稼働している間、一定間隔(デフォルトでは10秒)ごとに、
mun_resolver のサーバプロセスに対して、自身のサーバプロセスに接続しているクライアント数を送信します。

送信された情報をもとに、mun_resolver は mun_proxy に対する負荷分散を行ないます。
ここで、MunProxySessionToResolverServer::Send_ProxyResolver_SetTcpWeight() 関数、
および、MunProxySessionToResolverServer::Send_ProxyResolver_SetUdpWeight() 関数を呼び出し、
mun_resolver に対し、「mun_proxy 側に接続しているクライアント数」を送信します。
ここで、MunProxySessionToResolverServer.Send_ProxyResolver_SetTcpWeight() メソッド、
および、MunProxySessionToResolverServer.Send_ProxyResolver_SetUdpWeight() メソッドを呼び出し、
mun_resolver に対し、「mun_proxy 側に接続しているクライアント数」を送信します。
1. と同様に、mun_room サーバプロセスが稼働している間、一定間隔(デフォルトでは10秒)ごとに、
mun_master のサーバプロセスに対して、自身のサーバプロセスに接続しているクライアント数を送信します。

送信された情報をもとに、mun_master は mun_room に対する負荷分散を行ないます。
ここで、MunRoomSessionToMasterServer::Send_RoomMaster_SetWeight() 関数を呼び出し、
mun_master に対し、「mun_room 側に接続しているクライアント数」を送信します。
ここで、MunRoomSessionToMasterServer.Send_RoomMaster_SetWeight() メソッドを呼び出し、
mun_master に対し、「mun_room 側に接続しているクライアント数」を送信します。


シーケンス3:MUN クライアントから mun_resolver サーバへの接続

MUN クライアントが MUN サーバに接続してきたときの初回処理

  MUN クライアントが MUN サーバに接続する場合、その手始めに、mun_resolver のサーバプロセスに接続します。
  この時の、各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアント側で MonobitEngine.MonobitNetwork.ConnectServer() メソッドを実行したとき、
その最初の手続きとして、mun_resolver サーバプロセスに対して接続要求を行ないます。
mun_resolver が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
mun_resolver が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
上記 1. の処理を受けて、mun_resolver サーバプロセスは、MUN クライアントへ接続応答を返します。
この処理は MRS ライブラリ内で実行されます。

また、この接続応答に対し、MUN クライアントは内部処理によって、MUN クライアント側の秘密鍵と公開鍵を生成し、
次項 3. から説明する「鍵交換処理」を行ないます。
MUN クライアントの内部処理にて、秘密鍵と公開鍵を生成し終えた時点で、mun_resolver 側に公開鍵を送信します。
この処理は MUN クライアントの内部処理によって実行されます。
MRS ライブラリの内部処理にて、MUN クライアントから送られてきた公開鍵を受信した mun_resolver サーバ側で、
事前に 2. の段階で生成した公開鍵を送信します。

ここで送信されたデータを MUN クライアントが受信することで、以下の事象が成立します。
・ MUN クライアント側は「自身が生成した秘密鍵」と「mun_resolver サーバから送信されてきた公開鍵」を持つ
・ mun_resolver サーバ側は「自身が生成した秘密鍵」と「MUN クライアントから送信されてきた秘密鍵」を持つ
これにより、通信データに対し、公開鍵による暗号化、および秘密鍵による復号化を可能にします。
鍵交換が完了した時点で、MUN クライアントと mun_resolver サーバとの通信処理が開始されます。
とは言っても、mun_resolver に対し MUN クライアントが通信する目的は
「mun_proxy サーバの、MUN クライアントリスニングアドレス情報の取得」以外にありません。

この「mun_proxy サーバの接続情報取得要求」は、MUN の内部処理で行なわれ、mun_resolver サーバで受信します。
mun_resolver が要求を受けた時、以下の関数が呼び出されます。
 ・MUN クライアントが TCP 接続を使用している場合、MunResolverDatabase::Recv_Resolver_ResolveTcpAddress() 関数が呼び出される
 ・MUN クライアントが UDP 接続を使用している場合、MunResolverDatabase::Recv_Resolver_ResolveUdpAddress() 関数が呼び出される
mun_resolver が要求を受けた時、以下のメソッドが呼び出されます。
 ・MUN クライアントが TCP 接続を使用している場合、MunResolverDatabase.Recv_Resolver_ResolveTcpAddress() メソッドが呼び出される
 ・MUN クライアントが UDP 接続を使用している場合、MunResolverDatabase.Recv_Resolver_ResolveUdpAddress() メソッドが呼び出される
MUN クライアントの要求を受けて、mun_resolver サーバでは「mun_proxy サーバの送信処理」を実行します。
mun_resolver は「この時点でクライアント接続数が最も少ない mun_proxy サーバプロセスのアドレス情報」を、
以下の関数を使って MUN クライアントに通知します。
 ・MUN クライアントが TCP 接続を使用している場合、MunResolverSessionToClient::Send_Resolver_ResolveTcpAddressResult() 関数で通知する。
 ・MUN クライアントが UDP 接続を使用している場合、MunResolverSessionToClient::Send_Resolver_ResolveUdpAddressResult() 関数で通知する。
mun_resolver は「この時点でクライアント接続数が最も少ない mun_proxy サーバプロセスのアドレス情報」を、
以下のメソッドを使って MUN クライアントに通知します。
 ・MUN クライアントが TCP 接続を使用している場合、MunResolverSessionToClient.Send_Resolver_ResolveTcpAddressResult() メソッドで通知する。
 ・MUN クライアントが UDP 接続を使用している場合、MunResolverSessionToClient.Send_Resolver_ResolveUdpAddressResult() メソッドで通知する。
MUN クライアントが mun_proxy のクライアントリスニングアドレス情報を取得した時点で、mun_resolver とは切断します。
この処理は MUN クライアントの内部処理によって実行されます。
上記 7. の要求を受けて、mun_resolver サーバは切断処理を行ない、切断された旨の最終信号を MUN クライアントに送信します。
この処理は MRS ライブラリ内で実行されます。


シーケンス4:MUN クライアントから mun_proxy サーバへの接続

MUN クライアントによる MUN サーバへの本接続処理

  MUN クライアントが mun_proxy への接続情報を取得したら、間髪入れずに mun_proxy のサーバプロセスに接続します。
  この時の、各サーバプロセスで行われる以下の工程について、順に説明いたします。
mun_resolver サーバとの切断を完了し、かつ mun_proxy サーバの接続情報を取得した MUN クライアントは、
即座に mun_proxy サーバプロセスに対して接続要求を行ないます。
mun_proxy が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
mun_proxy が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
上記 1. の処理を受けて、mun_proxy サーバプロセスは、MUN クライアントへ接続応答を返します。
この処理は MRS ライブラリ内で実行されます。

また、この接続応答に対し、MUN クライアントは内部処理によって、MUN クライアント側の秘密鍵と公開鍵を生成し、
次項 3. から説明する「鍵交換処理」を行ないます。
MUN クライアントの内部処理にて、秘密鍵と公開鍵を生成し終えた時点で、mun_proxy 側に公開鍵を送信します。
この処理は MUN クライアントの内部処理によって実行されます。
MRS ライブラリの内部処理にて、MUN クライアントから送られてきた公開鍵を受信した mun_proxy サーバ側で、
事前に 2. の段階で生成した公開鍵を送信します。

ここで送信されたデータを MUN クライアントが受信することで、以下の事象が成立します。
・ MUN クライアント側は「自身が生成した秘密鍵」と「mun_proxy サーバから送信されてきた公開鍵」を持つ
・ mun_proxy サーバ側は「自身が生成した秘密鍵」と「MUN クライアントから送信されてきた秘密鍵」を持つ
これにより、通信データに対し、公開鍵による暗号化、および秘密鍵による復号化を可能にします。


シーケンス5:MUN クライアント認証処理

MUN クライアントに対するサーバ認証

  MUN クライアントと mun_proxy サーバプロセスとの相互接続が完了したら、続けて、MUN クライアントの認証制御を行ないます。
  この時の、各サーバプロセスで行われる以下の工程について、順に説明いたします。
認証処理に先立ち、MUN クライアントは mun_proxy サーバプロセスに対し、
MUN システム全体における「クライアント識別のためのユニークなID」の発行要求を行ないます。

この発行要求自体は、MUN クライアントの内部処理で行なわれます。
mun_proxy がID発行要求を受けた時、MunProxyDatabase::Recv_Proxy_Check() 関数を実行します。
mun_proxy がID発行要求を受けた時、MunProxyDatabase.Recv_Proxy_Check() メソッドを実行します。
mun_proxy サーバは、上述の 1. における MUN クライアントのID発行要求に応じて、必要に応じて カスタム認証処理を行ないます。
mun_proxy から認証用 Web サーバへのリクエスト処理は、MunProxyDatabase::Recv_Proxy_Check() 関数を通して実行します。

この手続きはデフォルトでは無効で、カスタム認証を実行するためには、別途認証モジュールを利用するためのサーバ設定が必要です。

詳しくは以下のページにて解説していますので、リンク先の内容をご覧ください。
  「■サーバサイドチュートリアル<カスタム認証を利用する>」 > 「認証モジュール利用するためのサーバ設定」
mun_proxy から認証用 Web サーバへのリクエスト処理は、MunProxyDatabase.Recv_Proxy_Check() メソッドを通して実行します。

この手続きはデフォルトでは無効で、カスタム認証を実行するためには、別途認証モジュールを利用するためのサーバ設定が必要です。

詳しくは以下のページにて解説していますので、リンク先の内容をご覧ください。
  「■サーバサイドチュートリアル<カスタム認証を利用する>」 > 「認証モジュール利用するためのサーバ設定」
認証用 Web サーバは、上述の 2. にて受け取ったアカウントデータに関して認証処理を行ない、結果を mun_proxy に通知します。
認証用 Web サーバから受信した認証結果は、mun_proxy サーバで受信し、
MunProxyDatabase::Recv_Proxy_CheckResult() 関数を通して、結果を解釈して MUN クライアントに通知します。

この手続きはデフォルトでは空実装で、カスタム認証を実行するためには、認証結果に伴う判定処理を実装する必要があります。

詳しくは以下のページにて解説していますので、リンク先の内容をご覧ください。
  「■サーバサイドチュートリアル<カスタム認証を利用する>」 > 「認証モジュール利用するためのサーバ設定」
認証用 Web サーバから受信した認証結果は、mun_proxy サーバで受信し、
MunProxyDatabase.Recv_Proxy_CheckResult() メソッドを通して、結果を解釈して MUN クライアントに通知します。

この手続きはデフォルトでは空実装で、カスタム認証を実行するためには、認証結果に伴う判定処理を実装する必要があります。

詳しくは以下のページにて解説していますので、リンク先の内容をご覧ください。
  「■サーバサイドチュートリアル<カスタム認証を利用する>」 > 「認証モジュール利用するためのサーバ設定」
カスタム認証を導入している場合には、mun_proxy サーバによる認証結果、および認証に成功した場合に「クライアント識別用ユニークID」について、MUN クライアントに通知します。
カスタム認証を導入していない場合には、認証への自動成功結果と「クライアント識別用ユニークID」について、MUN クライアントに通知します。

なお、この時点でカスタム認証に失敗していた場合、MUN クライアントは、OnCustomAuthenticationFailed() メソッドをコールバックします。
デフォルトではカスタム認証処理は無効化されているため、現時点では認証処理の自動成功結果と、「クライアント識別用ユニークID」について
MunProxySessionToClient::Send_Relay_Anything() 関数を通して MUN クライアントに送信します。
デフォルトではカスタム認証処理は無効化されているため、現時点では認証処理の自動成功結果と、「クライアント識別用ユニークID」について
MunProxySessionToClient.Send_Relay_Anything() 関数を通して MUN クライアントに送信します。
続けて、MUN クライアントから、アプリケーション単位での認証処理要求を送信します。
ここで送信される情報には、 以下の4種類のデータがあります。
・認証ID
  → UnityEditor 上で MonobitAuthenticationCode.asset として管理されている、32桁のGUIDコード
・MUN クライアントのバージョン
・アプリケーション名
  → MUN クライアント側での接続処理である MonobitEngine.MonobitNetwork.ConnectServer() メソッドの第1パラメータ
・アプリケーションバージョン
  → 上記「アプリケーション名」と、「MUN クライアントのバージョン」の連結文字列を含む、アプリケーションを特定するための情報
データの送信処理自体は、MUN クライアントの内部処理で実行します。

またこの時に受け取り手となる mun_proxy サーバプロセスは、mun_master サーバプロセスに対するリレーの役割を担うだけで、
特筆して何らかの処置を行なうわけではありません。
上記 5. の手続きにおいて、mun_proxy からリレーされて送信された情報について mun_master が受信し、ここで MUN クライアントについて、アプリケーションの認証処理を行ないます。
ここで行なわれる認証の結果、MUN クライアントはパーティションによって区切られた空間に配置され、
「認証IDやMUNのバージョン、アプリケーション情報」などが異なる場合、同一のロビー/ルームに入室することは絶対にできないようにしています。
MUN クライアントからの認証要求は、mun_proxy を通じて、ここで受け取ります。
認証処理を適宜実行し、その結果を最後に MunMasterSessionToProxyServer::Send_Master_CheckResult() 関数を使って、
mun_proxy 経由で MUN クライアントに返します。

なお、認証処理の本体は、下記画像の赤枠部分にある MunMasterDatabase::CreateClient() 関数で行なっています。
認証処理本体はここで行ないます。
ここで MUN バージョンのチェック、認証データに合わせたデフォルトロビー(マッチングルーム)への誘引、
ならびに1アプリケーションに対するクライアント数の上限チェックを行ないます。

なお、ここで実行している「クライアント上限チェック」は、
無償提供版の『オンプレミス型 MUN サーバ』の同時接続数制限(100クライアントまで)の上限チェックとは異なります。
この上限チェックは、弊社で提供している「MunTestServer」において、利用者が活用できるクライアント上限数を設定するためだけに用意されたもので、
無償提供版『オンプレミス型 MUN サーバ』においては、デフォルト設定で、この処理自体を「通過しない」ように組み込まれています。
 
そのため、該当するプログラムコード自体を削除したとしても、
無償提供版『オンプレミス型 MUN サーバ』の同時接続数制限(100クライアントまで)の制限が解除されるわけではありません。
MUN クライアントからの認証要求は、mun_proxy を通じて、ここで受け取ります。
認証処理を適宜実行し、その結果を最後に MunMasterSessionToProxyServer.Send_Master_CheckResult() メソッドを使って、
mun_proxy 経由で MUN クライアントに返します。

なお、認証処理の本体は、下記画像の赤枠部分にある MunMasterDatabase.CreateClient() メソッドで行なっています。
認証処理本体はここで行ないます。
ここで MUN バージョンのチェック、認証データに合わせたデフォルトロビー(マッチングルーム)への誘引、
ならびに1アプリケーションに対するクライアント数の上限チェックを行ないます。

なお、ここで実行している「クライアント上限チェック」は、
無償提供版の『オンプレミス型 MUN サーバ』の同時接続数制限(100クライアントまで)の上限チェックとは異なります。
この上限チェックは、弊社で提供している「MunTestServer」において、利用者が活用できるクライアント上限数を設定するためだけに用意されたもので、
無償提供版『オンプレミス型 MUN サーバ』においては、デフォルト設定で、この処理自体を「通過しない」ように組み込まれています。
 
そのため、該当するプログラムコード自体を削除したとしても、
無償提供版『オンプレミス型 MUN サーバ』の同時接続数制限(100クライアントまで)の制限が解除されるわけではありません。
上記 6. において、
  ・ C++ 版 MUN サーバであれば、MunMasterSessionToProxyServer::Send_Master_CheckResult() 関数
  ・ C# 版 mun_master であれば、MunMasterSessionToProxyServer.Send_Master_CheckResult() メソッド
によって送信された「MUN クライアントの認証結果」に合わせて、mun_master が発行する「プレイヤーID」、
および、当該クライアントが入室可能なロビー&ルーム情報を mun_proxy に送信します。

受け取った mun_proxy は、認証要求を送信してきた MUN クライアントに対して、mun_master から受信した情報をそのままリレーして返します。
上記 7. の処理にて、mun_proxy は、認証要求を送信してきた MUN クライアントに対して、mun_master から受信した情報をそのままリレーして返します。
MUN クライアントでは、mun_master から mun_proxy 経由で受信した情報に従い、認証可否を判定します。

認証に失敗していた場合、MUN クライアントは、OnConnectionFail() メソッドをコールバックします。

認証に成功していた場合、mun_master から送信されてきた「プレイヤーID」を MonobitEngine.MonobitNetwork.player.ID で取得できるように、
またロビー一覧情報を MonobitEngine.MonobitNetwork.LobbyDataList プロパティ で取得できるように、
ルーム一覧情報 を MonobitEngine.MonobitNetwork.GetRoomData メソッド で取得できるように、
適切なフィールド情報として格納します。


シーケンス6:ロビーの作成

MUN クライアントが入室可能なロビーを作成する

  MUN クライアントの認証手続きに成功したら、続けてロビーの作成処理に入ります。

  この時の、各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、ロビーを作成するための要求処理を送信します。

この処理は、MonobitEngine.MonobitNetwork.autoJoinLobby プロパティ を有効にしている場合には、
MUN クライアントの認証に成功し、その結果を MUN クライアントが受けたのと同時に行われます。

仮に MonobitEngine.MonobitNetwork.autoJoinLobby プロパティが有効でない場合には、
別途 MonobitEngine.MonobitNetwork.JoinLobby メソッド を実行することで、この要求を送信します。

要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
上記 1. の要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
実質的なロビー作成処理は mun_master で行われます。
MUN クライアントからのロビー作成要求は、mun_proxy を通じて、ここで受け取ります。

ロビー作成処理を実行し、その結果を最後に MunMasterSessionToProxyServer::Send_Master_Lobby_ForceJoinResult() 関数を使って
mun_proxy 経由で MUN クライアントに返します。

なお「ロビー作成処理」本体は、MunMasterDatabase::ForceJoinLobby() 関数(下記赤枠部分)で行なっています。
ここがロビー作成処理の本体です。

データベース上のロビー一覧と比較し、同名かつ同一属性を持つロビーがすでに存在している場合、作成処理をスキップして入室処理のみ行ないます。
そうでない場合にはロビーを作成してから入室します。

最後に MunMasterDatabase::UpdatedLobby() 関数(下記赤枠部分)を実行することにより、
同一認証コードでサーバに接続している他のクライアントに対して、作成したロビー情報に対して更新するよう促します。
MUN クライアントからのロビー作成要求は、mun_proxy を通じて、ここで受け取ります。

ロビー作成処理を実行し、その結果を最後に MunMasterSessionToProxyServer.Send_Master_Lobby_ForceJoinResult() メソッドを使って
mun_proxy 経由で MUN クライアントに返します。

なお「ロビー作成処理」本体は、MunMasterDatabase.ForceJoinLobby() メソッド(下記赤枠部分)で行なっています。
ここがロビー作成処理の本体です。

データベース上のロビー一覧と比較し、同名かつ同一属性を持つロビーがすでに存在している場合、作成処理をスキップして入室処理のみ行ないます。
そうでない場合にはロビーを作成してから入室します。

最後に MunMasterDatabase.UpdatedLobby() メソッド(下記赤枠部分)を実行することにより、
同一認証コードでサーバに接続している他のクライアントに対して、作成したロビー情報に対して更新するよう促します。
上記 2. の処理において、

  ・C++ 版 MUN サーバであれば MunMasterSessionToProxyServer::Send_Master_Lobby_ForceJoinResult() 関数
  ・C# 版 MUN サーバであれば MunMasterSessionToProxyServer.Send_Master_Lobby_ForceJoinResult() メソッド

によって、MUN クライアントが要求してきたロビー作成について、その結果を返します。

返す結果は、mun_master 側で処理した内容に応じて、以下のように変化します。
・ロビー作成に成功した場合、成功したことを通知するとともに、「作成かつ入室したロビーの情報」を返す。
・既に同一名・同一属性のロビーが作成済みであった場合、既に存在するロビーに入室したうえで、成功したことを通知するとともに、「入室したロビーの情報」を返す。
・ロビー作成数の上限(255)を超えて作成しようとした場合、あるいは何らかのエラーが発生した場合、ロビー作成に失敗したことを通知する。
上記 3. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

ロビー作成結果を受信した MUN クライアントでは、以下の処理を行ないます。
・ロビーの作成に成功した場合、MUN クライアントは、OnJoinedLobby() メソッドをコールバックします。
 同時に、MonobitEngine.MonobitNetwork.LobbyDataList プロパティ に格納されている、ロビー一覧情報を更新します。

・ロビーの作成に失敗した場合、MUN クライアントは、ロビー作成に失敗した旨のエラーログを出力します。
上記 3. および 4. の送信とは別に、「ロビー作成要求を受けた MUN クライアントを除く、同一認証IDで接続しているすべての MUN クライアント」に対して、
mun_master から mun_proxy 経由で、「誰かがロビーを作成した」ことによる、ロビー一覧情報の更新通知を行ないます。
ロビー作成要求を行なった MUN クライアント以外の同一認証IDで接続している MUN クライアントについては、
上記 3. で触れた MunMasterDatabase::ForceJoinLobby() 関数から呼ばれる、この関数内で処理します。

ここで、作成したばかりのロビー情報を共有するために、MunMasterSessionToProxyServer::Send_Master_Lobby_UpdateResult() 関数を使って送信します。
ロビー作成要求を行なった MUN クライアント以外の同一認証IDで接続している MUN クライアントについては、
上記 3. で触れた MunMasterDatabase.ForceJoinLobby() メソッドから呼ばれる、このメソッド内で処理します。

ここで、作成したばかりのロビー情報を共有するために、MunMasterSessionToProxyServer.Send_Master_Lobby_UpdateResult() メソッドを使って送信します。
上記 5. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

ロビー一覧情報の更新通知を受信した MUN クライアントは、
MonobitEngine.MonobitNetwork.LobbyDataList プロパティ に格納されている、ロビー一覧情報を更新します。


シーケンス7:ロビーへの入室

MUN クライアントが入室可能なロビーへ入室する

  MUN クライアントの認証手続きに成功したもののうち、既に作成しているロビーに入室する場合、
  各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、ロビーに入室するための要求処理を送信します。

この処理は、MonobitEngine.MonobitNetwork.autoJoinLobby プロパティ を有効にしている場合には、
MUN クライアントの認証に成功し、その結果を MUN クライアントが受けたのと同時に行われます。

仮に MonobitEngine.MonobitNetwork.autoJoinLobby プロパティが有効でない場合には、
別途 MonobitEngine.MonobitNetwork.JoinLobby メソッド を実行することで、この要求を送信します。

要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
上記 1. の要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
実質的なロビー入室処理は mun_master で行われます。
MUN クライアントからのロビー入室要求は、mun_proxy を通じて、ここで受け取ります。

ロビー入室処理を実行し、その結果を最後に MunMasterSessionToProxyServer::Send_Master_Lobby_ForceJoinResult() 関数を使って
mun_proxy 経由で MUN クライアントに返します。

なお「ロビー入室処理」本体は、MunMasterDatabase::ForceJoinLobby() 関数(下記赤枠部分)で行なっています。
ここがロビー入室処理の本体です。

データベース上のロビー一覧と比較し、同名かつ同一属性を持つロビーが存在しない場合、別途ロビー作成処理を行なってから入室処理を実行します。
そうでない場合には、既に存在するロビーに入室します。

最後に MunMasterDatabase::UpdatedLobby() 関数(下記赤枠部分)を実行することにより、
同一認証コードでサーバに接続している他のクライアントに対して、入室したロビー情報に対して更新するよう促します。
MUN クライアントからのロビー入室要求は、mun_proxy を通じて、ここで受け取ります。

ロビー入室処理を実行し、その結果を最後に MunMasterSessionToProxyServer.Send_Master_Lobby_ForceJoinResult() メソッドを使って
mun_proxy 経由で MUN クライアントに返します。

なお「ロビー入室処理」本体は、MunMasterDatabase.ForceJoinLobby() メソッド(下記赤枠部分)で行なっています。
ここがロビー入室処理の本体です。

データベース上のロビー一覧と比較し、同名かつ同一属性を持つロビーが存在しない場合、別途ロビー作成処理を行なってから入室処理を実行します。
そうでない場合には、既に存在するロビーに入室します。

最後に MunMasterDatabase.UpdatedLobby() メソッド(下記赤枠部分)を実行することにより、
同一認証コードでサーバに接続している他のクライアントに対して、入室したロビー情報に対して更新するよう促します。
上記 2. の処理において、

  ・C++ 版 MUN サーバであれば MunMasterSessionToProxyServer::Send_Master_Lobby_ForceJoinResult() 関数
  ・C# 版 MUN サーバであれば MunMasterSessionToProxyServer.Send_Master_Lobby_ForceJoinResult() メソッド

によって、MUN クライアントが要求してきたロビー入室処理について、その結果を返します。

返す結果は、mun_master 側で処理した内容に応じて、以下のように変化します。
・ロビーへの入室に成功した場合、成功したことを通知するとともに、「入室したロビーの情報」を返す。
・何らかのエラーが発生した場合、ロビー入室に失敗したことをエラーとして通知する。
上記 3. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

ロビー入室結果を受信した MUN クライアントでは、以下の処理を行ないます。
・ロビーへの入室に成功した場合、MUN クライアントは、OnJoinedLobby() メソッドをコールバックします。
 同時に、MonobitEngine.MonobitNetwork.LobbyDataList プロパティ に格納されている、ロビー一覧情報を更新します。

・ロビーへの入室に失敗した場合、MUN クライアントは、ロビー入室に失敗した旨のエラーログを出力します。
上記 3. および 4. の送信とは別に、「ロビー入室要求を受けた MUN クライアントを除く、同一認証IDで接続しているすべての MUN クライアント」に対して、
mun_master から mun_proxy 経由で、「誰かがロビーに入室した」ことによる、ロビー一覧情報の更新通知を行ないます。
ロビー入室要求を行なった MUN クライアント以外の同一認証IDで接続している MUN クライアントについては、
上記 3. で触れた MunMasterDatabase::ForceJoinLobby() 関数から呼ばれる、この関数内で処理します。

ここで、入室したばかりのロビー情報を共有するために、MunMasterSessionToProxyServer::Send_Master_Lobby_UpdateResult() 関数を使って送信します。
ロビー入室要求を行なった MUN クライアント以外の同一認証IDで接続している MUN クライアントについては、
上記 3. で触れた MunMasterDatabase.ForceJoinLobby() メソッドから呼ばれる、このメソッド内で処理します。

ここで、入室したばかりのロビー情報を共有するために、MunMasterSessionToProxyServer.Send_Master_Lobby_UpdateResult() メソッドを使って送信します。
上記 5. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

ロビー一覧情報の更新通知を受信した MUN クライアントは、
MonobitEngine.MonobitNetwork.LobbyDataList プロパティ に格納されている、ロビー一覧情報を更新します。


シーケンス8:プレイヤーの検索

MUN クライアントからプレイヤー名による検索を行なう

  mun_proxy に接続している MUN クライアントから、他の MUN クライアントの接続状態を調べるために、プレイヤー検索を行なう機能が用意されています。
  ここでは、プレイヤー検索を行なった場合の各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、プレイヤー名による接続状態を調査するリクエストを送信します。

この処理は、MUN クライアントが mun_proxy に接続している条件が整っていれば、
MonobitEngine.MonobitNetwork.SearchPlayers() メソッド により、任意のタイミングで実行することができます。

要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
上記 1. の要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
実質的なプレイヤーの検索要求処理は mun_master で行われます。
MUN クライアントからのプレイヤー検索要求は、mun_proxy を通じて、ここで受け取ります。

下記赤枠部分にて、mun_master が管理しているプレイヤーデータベースからプレイヤー情報を検索し、
  ・そのプレイヤーが同一認証IDで、同一の MUN サーバに接続してきているかどうか
  ・そのプレイヤーがオンラインである場合、どこかのルームに入室しているかどうか
について調査します。

調査した結果は、下記赤下線部の MunMasterSessionToProxyServer::Send_Master_SearchPlayerResult() 関数を使い、
mun_proxy 経由で MUN クライアントに返します。
MUN クライアントからのプレイヤー検索要求は、mun_proxy を通じて、ここで受け取ります。

下記赤枠部分にて、mun_master が管理しているプレイヤーデータベースからプレイヤー情報を検索し、
  ・そのプレイヤーが同一認証IDで、同一の MUN サーバに接続してきているかどうか
  ・そのプレイヤーがオンラインである場合、どこかのルームに入室しているかどうか
について調査します。

調査した結果は、下記赤下線部の MunMasterSessionToProxyServer.Send_Master_SearchPlayerResult() メソッドを使い、
mun_proxy 経由で MUN クライアントに返します。
上記 2. の処理において、

  ・C++ 版 MUN サーバであれば MunMasterSessionToProxyServer::Send_Master_SearchPlayerResult() 関数
  ・C# 版 MUN サーバであれば MunMasterSessionToProxyServer.Send_Master_SearchPlayerResult() メソッド

によって、MUN クライアントが要求してきたプレイヤー検索の結果を返します。

返す結果は、mun_master 側で処理した内容に応じて、以下のように変化します。
・そのプレイヤーがオンライン上に存在するか
・そのプレイヤーがルームに入室しているかどうか


シーケンス9:ルームの作成

MUN クライアントからルームの作成をリクエストする

  mun_proxy に接続している MUN クライアントから、ルームの作成要求を送信した場合における、
  各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、ルームを新規作成するリクエストを送信します。

この処理は、MUN クライアントが mun_proxy に接続している条件が整っていれば、
MonobitEngine.MonobitNetwork.CreateRoom() メソッド、または MonobitEngine.MonobitNetwork.JoinOrCreateRoom() メソッド により、
任意のタイミングで実行することができます。

要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
上記 1. の要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
実質的なルーム作成処理は mun_master で行われます。
MUN クライアントからのルーム作成要求は、mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに、MUN クライアントから要求を受けて作成するルームの設定に合わせて、
ルーム名や収容人数、ロビーからの可視設定や入室可否設定などの、各種パラメータを登録します。
パラメータ登録に成功した場合、作成したルームに対し、作成要求を出した MUN クライアントを「ルームホスト」として追加します。
  ※ この処理は、下図赤枠内で行なっています。

ルーム作成の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer::Send_Master_Room_CreateResult() 関数(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
MUN クライアントからのルーム作成要求は、mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに、MUN クライアントから要求を受けて作成するルームの設定に合わせて、
ルーム名や収容人数、ロビーからの可視設定や入室可否設定などの、各種パラメータを登録します。
パラメータ登録に成功した場合、作成したルームに対し、作成要求を出した MUN クライアントを「ルームホスト」として追加します。
  ※ この処理は、下図赤枠内で行なっています。

ルーム作成の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer.Send_Master_Room_CreateResult() メソッド(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
上記 2. の処理において、

  ・C++ 版 MUN サーバであれば MunMasterSessionToProxyServer::Send_Master_Room_CreateResult() 関数
  ・C# 版 MUN サーバであれば MunMasterSessionToProxyServer.Send_Master_Room_CreateResult() メソッド

によって、MUN クライアントが要求してきたルーム作成結果を、一旦 mun_proxy に返します。

ここで送信される情報には、ルーム作成の可否とともに、作成したルーム情報と、
そのルームが開設される mun_room サーバプロセスのアドレス情報などが含まれます。
上記 3. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

MUN クライアントでは、ルーム作成に成功している場合、OnCreatedRoom() メソッドをコールバックで返します。
また、この時点で mun_room サーバのアドレスを取得しますので、続けて mun_room サーバへの接続を開始します。

 なお、ルーム作成に失敗している場合には、エラー出力と同時に、
OnCreatedRoomFailed () メソッド をコールバックします。
上記 3. および 4. の送信とは別に、「ルーム作成要求を受けた MUN クライアントを除く、同一ロビーに入室しているすべての MUN クライアント」に対して、
mun_master から mun_proxy 経由で、「誰かがルームを作成した」ことによる、ルーム一覧情報の更新通知を行ないます。
上記 3. で触れた MunMasterDatabase::Recv_Master_Room_Create() 関数内で、ルームホストの入室処理である
MunMasterDatabase::JoinRoom() 関数処理内にて、

  MunMasterDatabase::JoinRoom() 関数
    → MunMasterDatabase::UpdateRoom() 関数
      → MunMasterDatabase::UpdatedRoom() 関数

が呼ばれます。

ここで、作成&入室したばかりのルーム情報を、同一ロビー内クライアントで共有するために、
MunMasterSessionToProxyServer::Send_Master_Room_UpdateResult() 関数を使って送信します。
上記 3. で触れた MunMasterDatabase.Recv_Master_Room_Create() メソッド内で、ルームホストの入室処理である
MunMasterDatabase.JoinRoom() メソッド処理内にて、

  MunMasterDatabase::JoinRoom() メソッド
    → MunMasterDatabase::UpdateRoom() メソッド
      → MunMasterDatabase::UpdatedRoom() メソッド

が呼ばれます。

ここで、作成&入室したばかりのルーム情報を、同一ロビー内クライアントで共有するために、
MunMasterSessionToProxyServer.Send_Master_Room_UpdateResult() メソッドを使って送信します。
上記 4. の段階で、ルーム作成に成功した MUN クライアントは、そのルームが開設される mun_room サーバプロセスの
クライアントリスニングアドレス情報を受け取りますので、即座に mun_room サーバプロセスに対して接続要求を行ないます。
mun_room が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
mun_room が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
上記 7. の処理を受けて、mun_room サーバプロセスは、MUN クライアントへ接続応答を返します。
この処理は MRS ライブラリ内で実行されます。

また、この接続応答に対し、MUN クライアントは内部処理によって、MUN クライアント側の秘密鍵と公開鍵を生成し、
次項 9. から説明する「鍵交換処理」を行ないます。
MUN クライアントの内部処理にて、秘密鍵と公開鍵を生成し終えた時点で、mun_room 側に公開鍵を送信します。
この処理は MUN クライアントの内部処理によって実行されます。
MRS ライブラリの内部処理にて、MUN クライアントから送られてきた公開鍵を受信した mun_room サーバ側で、
事前に 8. の段階で生成した公開鍵を送信します。

ここで送信されたデータを MUN クライアントが受信することで、以下の事象が成立します。
・ MUN クライアント側は「自身が生成した秘密鍵」と「mun_room サーバから送信されてきた公開鍵」を持つ
・ mun_room サーバ側は「自身が生成した秘密鍵」と「MUN クライアントから送信されてきた秘密鍵」を持つ
これにより、通信データに対し、公開鍵による暗号化、および秘密鍵による復号化を可能にします。
続けて、MUN クライアントから mun_room サーバプロセスに対し、ルームへのログイン要求を送信します。
この処理は、「あらかじめ mun_master でルーム開設を行なった MUN クライアント」と「mun_room サーバプロセスに接続してきた MUN クライアント」が一致するか、
その整合チェックのために行われます。
この処理自体は、MUN クライアントの内部処理として実行されます。
上記 11. について mun_room サーバが受信した段階で、mun_room からリレーされて、mun_master にログイン処理要求が送信されます。
ログイン処理は、一旦 mun_master で整合処理を行なうところから始まります。
mun_room サーバプロセスから要求を受けた MUN クライアントのログイン要求は、ここで処理されます。
ここでは上記 2. の段階で mun_master に登録された「ルームデータベース」内の MUN クライアントの情報と、
mun_room サーバプロセスから送信されてきた MUN クライアント情報について、プレイヤー識別用ユニークID が一致するか判別します。

整合性が確認できた段階で、ルームデータベースに含まれる「開設したルームに関するすべての情報」を
MunMasterSessionToRoomServer::Send_RoomMaster_LoginPlayerResult() 関数を使って、mun_room サーバに送信します。
ここで述べている「開設したルームに関するすべての情報」については、主に以下の情報を含みます。
  ・ルーム名
  ・ルームパラメータ(ルーム収容人数、ロビーからの可視設定、入室可否設定など)
  ・ルームカスタムパラメータ(MUN クライアント側で任意に設定された、ルーム独自のパラメータ)
  ・ルーム内に所属するプレイヤー情報
  ・ルームホストのプレイヤー情報
mun_room サーバプロセスから要求を受けた MUN クライアントのログイン要求は、ここで処理されます。
ここでは上記 2. の段階で mun_master に登録された「ルームデータベース」内の MUN クライアントの情報と、
mun_room サーバプロセスから送信されてきた MUN クライアント情報について、プレイヤー識別用ユニークID が一致するか判別します。

整合性が確認できた段階で、ルームデータベースに含まれる「開設したルームに関するすべての情報」を
MunMasterSessionToRoomServer.Send_RoomMaster_LoginPlayerResult() メソッドを使って、mun_room サーバに送信します。
ここで述べている「開設したルームに関するすべての情報」については、主に以下の情報を含みます。
  ・ルーム名
  ・ルームパラメータ(ルーム収容人数、ロビーからの可視設定、入室可否設定など)
  ・ルームカスタムパラメータ(MUN クライアント側で任意に設定された、ルーム独自のパラメータ)
  ・ルーム内に所属するプレイヤー情報
  ・ルームホストのプレイヤー情報
上記 12. において、
  ・ C++ 版 MUN サーバであれば、MunMasterSessionToProxyServer::Send_RoomMaster_LoginPlayerResult() 関数
  ・ C# 版 mun_master であれば、MunMasterSessionToProxyServer.Send_RoomMaster_LoginPlayerResult() メソッド
によって「ルームログイン情報」を受け取った mun_room 側で、MUN クライアントのルームログイン処理を実行します。
mun_master から受信したルーム情報は一旦ここで処理されます。
ここでは、mun_master から受信した情報について、MunRoomSessionToClient::Send_Room_LoginPlayerResult() 関数で、MUN クライアントに送信します。
また、mun_room 上のルームデータベースに対するルーム情報登録処理は、後述する MunRoomDatabase::LoginPlayer() 関数で行ないます。
mun_master から受信したルーム情報について、mun_room 上のルームデータベースに登録します。
ルーム作成段階において、mun_room にはまだルーム情報が登録されていませんので、
ここでは、ルームデータベースへの登録処理(以下の赤枠部分)が実行されます。
mun_master から受信したルーム情報は一旦ここで処理されます。
ここでは、mun_master から受信した情報について、MunRoomSessionToClient.Send_Room_LoginPlayerResult() メソッドで、MUN クライアントに送信します。
また、mun_room 上のルームデータベースに対するルーム情報登録処理は、後述する MunRoomDatabase.LoginPlayer() メソッドで行ないます。
mun_master から受信したルーム情報について、mun_room 上のルームデータベースに登録します。
ルーム作成段階において、mun_room にはまだルーム情報が登録されていませんので、
ここでは、ルームデータベースへの登録処理(以下の赤枠部分)が実行されます。
上記 13. の処理にて、
  ・ C++ 版 MUN サーバであれば、MunRoomSessionToClient::Send_Room_LoginPlayerResult() 関数
  ・ C# 版 MUN サーバであれば、MunRoomSessionToClient.Send_Room_LoginPlayerResult() メソッド
によって送信されたルームログイン結果について、MUN クライアントにて受信します。

この時点でルーム入室に成功していた場合、mun_master から送信されてきたルーム情報は ルームパラメータ で取得できるように、
またルーム一覧情報 を MonobitEngine.MonobitNetwork.GetRoomData メソッド で取得できるように、
適切なフィールド情報として格納します。
同時に、OnJoinedRoom() メソッド をコールバックします。

なお、ルーム入室に失敗することはほぼあり得ませんが、仮に失敗していた場合、
MUN クライアントにて OnJoinRoomFailed() メソッドをコールバックします。


シーケンス10:ルームへの入室

MUN クライアントからルームへの入室をリクエストする

  mun_proxy に接続している MUN クライアントから、ルームへの入室要求を送信した場合における、
  各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、ルームへ入室するためのリクエストを送信します。

この処理は、MUN クライアントが mun_proxy に接続している条件が整っていれば、
MonobitEngine.MonobitNetwork.JoinRoom() メソッド、MonobitEngine.MonobitNetwork.JoinOrCreateRoom() メソッド、
MonobitEngine.MonobitNetwork.JoinRandomRoom() メソッドのいずれか
により、任意のタイミングで実行することができます。

要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
上記 1. の要求を受信した mun_proxy は、そのまま mun_master に情報を送信します。
実質的なルーム入室処理は mun_master で行われます。
MUN クライアントから MonobitEngine.MonobitNetwork.JoinRoom() メソッド、あるいは MonobitEngine.MonobitNetwork.JoinOrCreateRoom() メソッドにより
リクエスト送信されたルーム入室要求は、mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに、MUN クライアントから指定されたルームに対する入室処理を、
下図赤枠の MunMasterDatabase::JoinRoom() 関数内で行ないます。

入室の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer::Send_Master_Room_JoinResult() 関数(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
MUN クライアントから MonobitEngine.MonobitNetwork.JoinRandomRoom() メソッドによりリクエスト送信されたルーム入室要求は、
mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに登録されているルームの中から、MUN クライアントから指定されたフィルターに適合する
ルームを1つ選択して取得する処理を、下図赤枠の MunMasterDatabase::JoinRandomRoom() 関数内で行ないます。

入室の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer::Send_Master_Room_JoinRandomResult() 関数(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
MUN クライアントから MonobitEngine.MonobitNetwork.JoinRoom() メソッド、あるいは MonobitEngine.MonobitNetwork.JoinOrCreateRoom() メソッドにより
リクエスト送信されたルーム入室要求は、mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに、MUN クライアントから指定されたルームに対する入室処理を、
下図赤枠の MunMasterDatabase.JoinRoom() メソッド内で行ないます。

入室の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer.Send_Master_Room_JoinResult() メソッド(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
MUN クライアントから MonobitEngine.MonobitNetwork.JoinRandomRoom() メソッドによりリクエスト送信されたルーム入室要求は、
mun_proxy を通じて、ここで受け取ります。

ここでは、mun_master が管理しているルームデータベースに登録されているルームの中から、MUN クライアントから指定されたフィルターに適合する
ルームを1つ選択して取得する処理を、下図赤枠の MunMasterDatabase.JoinRandomRoom() メソッド内で行ないます。

入室の成否、ならびに成功した場合、そのルームが開設している mun_room のクライアントリスニングアドレス情報について、
MunMasterSessionToProxyServer.Send_Master_Room_JoinRandomResult() メソッド(下図赤線)を使い、mun_proxy 経由で MUN クライアントに通知します。
上記 2. の処理において、

  ・C++ 版 MUN サーバであれば、
    MunMasterSessionToProxyServer::Send_Master_Room_JoinResult() 関数
    MunMasterSessionToProxyServer::Send_Master_Room_JoinRandomResult() 関数
  ・C# 版 MUN サーバであれば、
    MunMasterSessionToProxyServer.Send_Master_Room_JoinResult() メソッド
    MunMasterSessionToProxyServer.Send_Master_Room_JoinRandomResult()メソッド

によって、MUN クライアントが要求してきたルーム入室結果を、一旦 mun_proxy に返します。

ここで送信される情報には、ルーム入室の可否とともに、入室したルーム情報と、
そのルームが開設されている mun_room サーバプロセスのアドレス情報などが含まれます。
上記 3. の処理にて受信した mun_proxy は、MUN クライアントに対しリレーで返信します。

MUN クライアントでは、ルーム入室に成功している場合、引き続き mun_room サーバへの接続を開始します。
ルーム入室に失敗している場合には、エラー出力と同時に、OnJoinRoomFailed() メソッド をコールバックします。
上記 4. の段階で、ルーム入室に成功した MUN クライアントは、そのルームが開設される mun_room サーバプロセスの
クライアントリスニングアドレス情報を受け取りますので、即座に mun_room サーバプロセスに対して接続要求を行ないます。
mun_room が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
mun_room が接続要求を受けた時、MUN クライアントごとの暗号鍵(秘密鍵と公開鍵)を生成します。
ここで生成された鍵情報は、後述の鍵交換処理で使用されます。
上記 5. の処理を受けて、mun_room サーバプロセスは、MUN クライアントへ接続応答を返します。
この処理は MRS ライブラリ内で実行されます。

また、この接続応答に対し、MUN クライアントは内部処理によって、MUN クライアント側の秘密鍵と公開鍵を生成し、
次項 7. から説明する「鍵交換処理」を行ないます。
MUN クライアントの内部処理にて、秘密鍵と公開鍵を生成し終えた時点で、mun_room 側に公開鍵を送信します。
この処理は MUN クライアントの内部処理によって実行されます。
MRS ライブラリの内部処理にて、MUN クライアントから送られてきた公開鍵を受信した mun_room サーバ側で、
事前に 6. の段階で生成した公開鍵を送信します。

ここで送信されたデータを MUN クライアントが受信することで、以下の事象が成立します。
・ MUN クライアント側は「自身が生成した秘密鍵」と「mun_room サーバから送信されてきた公開鍵」を持つ
・ mun_room サーバ側は「自身が生成した秘密鍵」と「MUN クライアントから送信されてきた秘密鍵」を持つ
これにより、通信データに対し、公開鍵による暗号化、および秘密鍵による復号化を可能にします。
続けて、MUN クライアントから mun_room サーバプロセスに対し、ルームへのログイン要求を送信します。
この処理は、「あらかじめ mun_master でルーム開設を行なった MUN クライアント」と「mun_room サーバプロセスに接続してきた MUN クライアント」が一致するか、
その整合チェックのために行われます。
この処理自体は、MUN クライアントの内部処理として実行されます。
上記 11. について mun_room サーバが受信した段階で、mun_room からリレーされて、mun_master にログイン処理要求が送信されます。
ログイン処理は、一旦 mun_master で整合処理を行なうところから始まります。
mun_room サーバプロセスから要求を受けた MUN クライアントのログイン要求は、ここで処理されます。
ここでは上記 2. の段階で mun_master に登録された「ルームデータベース」内の MUN クライアントの情報と、
mun_room サーバプロセスから送信されてきた MUN クライアント情報について、プレイヤー識別用ユニークID が一致するか判別します。

整合性が確認できた段階で、ルームデータベースに含まれる「開設したルームに関するすべての情報」を
MunMasterSessionToRoomServer::Send_RoomMaster_LoginPlayerResult() 関数を使って、mun_room サーバに送信します。
ここで述べている「開設したルームに関するすべての情報」については、主に以下の情報を含みます。
  ・ルーム名
  ・ルームパラメータ(ルーム収容人数、ロビーからの可視設定、入室可否設定など)
  ・ルームカスタムパラメータ(MUN クライアント側で任意に設定された、ルーム独自のパラメータ)
  ・ルーム内に所属するプレイヤー情報
  ・ルームホストのプレイヤー情報
mun_room サーバプロセスから要求を受けた MUN クライアントのログイン要求は、ここで処理されます。
ここでは上記 2. の段階で mun_master に登録された「ルームデータベース」内の MUN クライアントの情報と、
mun_room サーバプロセスから送信されてきた MUN クライアント情報について、プレイヤー識別用ユニークID が一致するか判別します。

整合性が確認できた段階で、ルームデータベースに含まれる「開設したルームに関するすべての情報」を
MunMasterSessionToRoomServer.Send_RoomMaster_LoginPlayerResult() メソッドを使って、mun_room サーバに送信します。
ここで述べている「開設したルームに関するすべての情報」については、主に以下の情報を含みます。
  ・ルーム名
  ・ルームパラメータ(ルーム収容人数、ロビーからの可視設定、入室可否設定など)
  ・ルームカスタムパラメータ(MUN クライアント側で任意に設定された、ルーム独自のパラメータ)
  ・ルーム内に所属するプレイヤー情報
  ・ルームホストのプレイヤー情報
上記 10. において、
  ・ C++ 版 MUN サーバであれば、MunMasterSessionToProxyServer::Send_RoomMaster_LoginPlayerResult() 関数
  ・ C# 版 mun_master であれば、MunMasterSessionToProxyServer.Send_RoomMaster_LoginPlayerResult() メソッド
によって「ルームログイン情報」を受け取った mun_room 側で、MUN クライアントのルームログイン処理を実行します。
mun_master から受信したルーム情報は一旦ここで処理されます。
ここでは、mun_master から受信した情報について、MunRoomSessionToClient::Send_Room_LoginPlayerResult() 関数で、MUN クライアントに送信します。
また、mun_room 上のルームデータベースに対するルーム情報登録処理は、後述する MunRoomDatabase::LoginPlayer() 関数で行ないます。
mun_master から受信したルーム情報について、既に作成済みのルーム情報が mun_room 上のルームデータベースに存在しますので、
ここでは、MunRoomSessionToClient::Send_Room_JoinedPlayerResult() 関数を用いて、
「同一ルーム内にいる、他のクライアント」に対し、「入室してきたプレイヤーの情報」の送信処理を実行します(以下の赤枠部分)。
mun_master から受信したルーム情報は一旦ここで処理されます。
ここでは、mun_master から受信した情報について、MunRoomSessionToClient.Send_Room_LoginPlayerResult() メソッドで、MUN クライアントに送信します。
また、mun_room 上のルームデータベースに対するルーム情報登録処理は、後述する MunRoomDatabase.LoginPlayer() メソッドで行ないます。
mun_master から受信したルーム情報について、既に作成済みのルーム情報が mun_room 上のルームデータベースに存在しますので、
ここでは、MunRoomSessionToClient.Send_Room_JoinedPlayerResult() メソッドを用いて、
「同一ルーム内にいる、他のクライアント」に対し、「入室してきたプレイヤーの情報」の送信処理を実行します(以下の赤枠部分)。
上記 11. の処理にて、
  ・ C++ 版 MUN サーバであれば、MunRoomSessionToClient::Send_Room_LoginPlayerResult() 関数
  ・ C# 版 MUN サーバであれば、MunRoomSessionToClient.Send_Room_LoginPlayerResult() メソッド
によって送信されたルームログイン結果について、MUN クライアントにて受信します。

この時点でルーム入室に成功していた場合、mun_master から送信されてきたルーム情報は ルームパラメータ で取得できるように、
またルーム一覧情報 を MonobitEngine.MonobitNetwork.GetRoomData メソッド で取得できるように、
適切なフィールド情報として格納します。
同時に、OnJoinedRoom() メソッド をコールバックします。

なお、ここでルーム入室に失敗することはほぼあり得ませんが、仮に失敗していた場合、
MUN クライアントにて OnJoinRoomFailed() メソッドをコールバックします。
上記 11. の処理にて、
  ・ C++ 版 MUN サーバであれば、MunRoomSessionToClient::Send_Room_JoinedPlayerResult() 関数
  ・ C# 版 MUN サーバであれば、MunRoomSessionToClient.Send_Room_JoinedPlayerResult() メソッド
によって送信された「とあるクライアントがルームに入室してきた」ことを通知する情報を、mun_room 側で受信します。

受信した mun_room 側では、そのまま MUN クライアントに対してリレー送信します。
上記 13. の処理にて、mun_room 側からの送信を受けた MUN クライアント側では、
ルーム内に別のクライアントが入室してきたことを受けて、以下の処理を実行します。
  ・ ルームパラメータ に含まれるルーム情報について、情報を更新します。
  ・ OnOtherPlayerConnected () メソッド をコールバックします。


シーケンス11:ルーム内情報の更新処理

同一ルームに所属する MUN クライアント間における、各種データの送受信処理

  mun_room に接続している MUN クライアントについて、ルーム内情報となる各種データを送受信するときの、
  各サーバプロセスで行われる以下の工程について、順に説明いたします。
上記 1. を受信した mun_room は、単独あるいは複数の MUN クライアントに対し、unicast/broadcast で送信します。
mun_room が RPC メッセージを受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(STREAM::TARGETS_ALL) か、unicast(STREAM::TARGETS_PLAYER) かによって、送信先の MUN クライアントを選定し、
MunRoomSessionToClient::Send_Room_RPCBufferResult() 関数を使って、送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して
送信元のデータをダイレクトに転送します。
mun_room が RPC メッセージを受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(mun.STREAM.TARGETS_TYPE.TARGETS_ALL) か、unicast(mun.STREAM.TARGETS_TYPE.TARGETS_PLAYER) かによって、
送信先の MUN クライアントを選定し、 MunRoomSessionToClient.Send_Room_RPCBufferResult() メソッドを使って、
送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して、送信元のデータをダイレクトに転送します。
MUN クライアントから mun_room を経由して、他クライアントに対してオブジェクト同期情報を送信します。

この処理は、MUN クライアント側で MonobitTransformView コンポーネントMonobitAnimatorView コンポーネント
あるいは OnMonobitSerializeView メソッド による送信処理により、ルームに入室している最中であれば、
MonobitEngine.MonobitNetwork.updateStreamRate プロパティ で設定したタイミングで実行することができます。
上記 3. を受信した mun_room は、単独あるいは複数の MUN クライアントに対し、unicast/broadcast で送信します。
mun_room がオブジェクト同期情報を受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(STREAM::TARGETS_ALL) か、unicast(STREAM::TARGETS_PLAYER) かによって、送信先の MUN クライアントを選定し、
MunRoomSessionToClient::Send_Room_RPCResult() 関数を使って、送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して
送信元のデータをダイレクトに転送します。
mun_room がオブジェクト同期情報を受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(mun.STREAM.TARGETS_TYPE.TARGETS_ALL) か、unicast(mun.STREAM.TARGETS_TYPE.TARGETS_PLAYER) かによって、
送信先の MUN クライアントを選定し、 MunRoomSessionToClient.Send_Room_RPCResult() メソッドを使って、
送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して、送信元のデータをダイレクトに転送します。
上記 5. を受信した mun_room は、単独あるいは複数の MUN クライアントに対し、unicast/broadcast で送信します。
mun_room が各種ルームパラメータを受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(STREAM::TARGETS_ALL) か、unicast(STREAM::TARGETS_PLAYER) かによって、送信先の MUN クライアントを選定し、
MunRoomSessionToClient::Send_Room_RPCResult() 関数を使って、送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して
送信元のデータをダイレクトに転送します。
mun_room が各種ルームパラメータを受信したとき、この処理に到達します。

ここでは、送信方法が broadcast(mun.STREAM.TARGETS_TYPE.TARGETS_ALL) か、unicast(mun.STREAM.TARGETS_TYPE.TARGETS_PLAYER) かによって、
送信先の MUN クライアントを選定し、 MunRoomSessionToClient.Send_Room_RPCResult() メソッドを使って、
送信元の MUN クライアントとは異なる、単独または複数の MUN クライアントに対して、送信元のデータをダイレクトに転送します。
mun_room から、同一ルームに存在するすべての MUN クライアントに対し、RPC メッセージを送信します。

この処理については、mun_room 側で RPC メッセージの送信処理 を組み込んでいた場合に、適宜実行されます。


シーケンス12:ルームからの退室

MUN クライアントから、ルームからの退室リクエストを送信する

  mun_room に接続している MUN クライアントから、ルームからの退室要求を送信した場合における、
  各サーバプロセスで行われる以下の工程について、順に説明いたします。
MUN クライアントから mun_proxy に対し、ルームからの退室要求を送信します。

この処理は、MUN クライアント側がルームに入室している最中であれば、
MonobitEngine.MonobitNetwork.LeaveRoom メソッド によって、任意のタイミングで実行することができます。
上記 1. を受信した mun_proxy は、そのまま mun_master に対しリレーで送信します。
mun_room からの退室処理は、mun_master 側で処理されます。
MUN クライアントから mun_proxy を経由して、ルームからの退室リクエストを受信したとき、この処理に到達します。

ここでは、MunMasterDatabase::LeaveRoom() 関数により、mun_master のルームデータベースからの、該当する MUN クライアントの除外処理、
ならびに、後述する 3. における、mun_room サーバに対して「ルームからの特定プレイヤーのログアウト処理」をリクエストします。

また退室結果については、MunMasterSessionToProxyServer::Send_Master_Room_LeaveResult() 関数を使って、
mun_proxy を経由して、リクエスト元の MUN クライアントに結果を通知します。
MUN クライアントから mun_proxy を経由して、ルームからの退室リクエストを受信したとき、この処理に到達します。

ここでは、MunMasterDatabase.LeaveRoom() メソッドにより、mun_master のルームデータベースからの、該当する MUN クライアントの除外処理、
ならびに、後述する 3. における、mun_room サーバに対して「ルームからの特定プレイヤーのログアウト処理」をリクエストします。

また退室結果については、MunMasterSessionToProxyServer.Send_Master_Room_LeaveResult() メソッドを使って、
mun_proxy を経由して、リクエスト元の MUN クライアントに結果を通知します。
上記 2. において、mun_master から mun_room に対し、ルーム退室要求をリクエストした MUN クライアントに対してログアウト処理をリクエストします。
mun_master におけるルーム退室処理において、上記 2. における MunMasterDatabase::Recv_Master_Room_Leave() 関数から、

  MunMasterDatabase::Recv_Master_Room_Leave() 関数
    → MunMasterDatabase::LeaveRoom() 関数
      → MunMasterDatabase::LeftRoom() 関数

が呼び出され、ここで、MunMasterSessionToRoomServer::Send_RoomMaster_LogoutPlayerResult() 関数を使って、
mun_room に対し、ルーム退室要求をリクエストした MUN クライアントに対してログアウト処理をリクエストします。
mun_master におけるルーム退室処理において、上記 2. における MunMasterDatabase.Recv_Master_Room_Leave() メソッドから、

  MunMasterDatabase.Recv_Master_Room_Leave() メソッド
    → MunMasterDatabase.LeaveRoom() メソッド
      → MunMasterDatabase.LeftRoom() メソッド

が呼び出され、ここで、MunMasterSessionToRoomServer.Send_RoomMaster_LogoutPlayerResult() メソッドを使って、
mun_room に対し、ルーム退室要求をリクエストした MUN クライアントに対してログアウト処理をリクエストします。
上記 3. により、mun_room におけるルーム退室を実行し、その結果を「退室したルームに属する、他の MUN クライアント」に対し、退室結果を通知します。
mun_master からの「特定の MUN クライアントの退室通知」の送信データは、ここで受信処理がなされます。

ここでは、MunRoomDatabase::RemovePlayer() 関数により、mun_room 上で管理しているルームデータベースから、退室した MUN クライアントの情報を削除するとともに、
MunRoomSessionToClient::Send_Room_Left_PlayerResult() 関数により、「退室したルームに属する、他の MUN クライアント」に対し、退室結果を通知します。
mun_master からの「特定の MUN クライアントの退室通知」の送信データは、ここで受信処理がなされます。

ここでは、MunRoomDatabase.RemovePlayer() メソッドにより、mun_room 上で管理しているルームデータベースから、退室した MUN クライアントの情報を削除するとともに、
MunRoomSessionToClient.Send_Room_Left_PlayerResult() メソッドにより、「退室したルームに属する、他の MUN クライアント」に対し、退室結果を通知します。

なお、通知を受けた MUN クライアント側では、ルームから別のクライアントが退室したことを受けて、以下の処理を実行します。
  ・ ルームパラメータ に含まれるルーム情報について、情報を更新します。
  ・ OnOtherPlayerDisconnected() メソッド をコールバックします。
上記 2. における

  ・C++ 版 MUN サーバの場合 :MunMasterSessionToProxyServer::Send_Master_Room_LeaveResult() 関数
  ・C# 版 MUN サーバの場合 :MunMasterSessionToProxyServer.Send_Master_Room_LeaveResult() メソッド

によって、ルームからの退室結果を mun_proxy に通知します。

通知を受けた mun_proxy 側では、ルーム退室要求を送信してきた MUN クライアントに対し、退室結果をリレーで返信します。
上記 5. によって、mun_master からのルーム退室結果は、mun_proxy を経由して、リクエスト送信元の MUN クライアントに送られます。

結果を受けた MUN クライアント側では、OnLeftRoom メソッド をコールバックします。
同時に、mun_room サーバに対する切断処理を実行します。