再接続処理

目次

  概要
  事前知識
  サーバ切断に備えて、再生成情報を保持する
  途中切断からの再接続
  実際のサンプルとして RandomMatchingRecoonnect があります!


概要

途中切断からの復旧処理について

  この項目も技術的な話を取り上げます。
  現時点で MUN で実現可能な「途中切断からの復旧処理」についてです。

  有線でのネットワーク通信ではあまり考えられませんが、Android端末や iOS端末などでは、
  回線不良による途中切断は大いに考えられます。(リアルタイム型ネットワーク通信においては致命的なのですが)

  MUNでは途中切断したクライアントに対し「オフラインモード」で動作を継続させることもできますが、
  そういう方法ではなく「元々入室していたルームに再接続して入室する」という手段を取ることも不可能ではありません。

  ここでは途中切断からの復旧処理について、対処方法を述べていきます。


事前知識

サーバから切断した時の、一般的なアプリケーションの挙動について

  サーバから切断した場合、以下のような挙動を取るのがベターと言えます。
・サーバから切断した時点で、自分自身が生成したオブジェクトは、ネットワーク越しに消失するため、
 再接続した時に、クライアント側からネットワーク越しに再生成をします。

・途中断線の場合、サーバから切断→再接続までは自動化させます。
 (今回は省略しますが、できれば、「再接続しますか?」のアナウンスがあると良いです。)


サーバ切断に備えて、再生成情報を保持する

基本的に再生成に必要な情報は、Instantiate で必要な情報に等しい。

  サーバ切断に備えて、あらかじめ Update を走らせている箇所にて、再生成情報を保持します。
  再生成はネットワーク越しに行ないますので、MonobitEngine.MonobitNetwork.Instantiate を使います。

  途中切断からの再生成の場合、MonobitEngine.MonobitNetwork.Instantiate で同じ場所に復帰させるためには、
  「座標」と「回転値」が必要です。これをバックアップする機構を作ります。

  おおまかな流れとしては以下のような形です。
  任意のタイミングで、gameObj が null になった場合に再生成される仕組みです。
using System;
using UnityEngine;

public class Foo : MonobitEngine.MonoBehaviour
{
    // プレハブ名(仮)
    string prefabName = "prefabName";

    // バックアップ対象となるゲームオブジェクトと、その座標値・回転量の情報
  GameObject gameObj = null;
    Vector3 position = Vector3.zero;
    Quaternion rotation = Quaternion.identity;

    public void Update()
    {
        // Network.Instantiate を実行する。
        // 説明上、「ルーム内に入室していて、オブジェクトが生成されていないとき」にリアルタイムに生成するものとする。
        if( MonobitEngine.MonobitNetwork.isConnect && MonobitEngine.MonobitNetwork.inRoom )
        {
            if( gameObj == null )
            {
                gameObj = MonobitEngine.MonobitNetwork.Instantiate( prefabName, position, rotation, 0 );
            }
            // 座標値・回転量の退避
            position = gameObj.transform.position;
            rotation = gameObj.transform.rotation;
        }

        /*
         * その他、gameObj の制御や、接続制御など。
         */
   }
}


途中切断からの再接続

各種コールバックが起動するので、そこから再接続の手順を踏む

  後は切断されたときに再接続するまでの流れを組んでおけばOKです。
  ロジックとしては単純で、先に説明している 接続コールバック を利用します。
・切断された場合 OnDisconnectedFromServer のコールバックが呼び出される。
  → ひとまずサーバに再接続する。

・再接続が完了し、ロビーに入室できたら、OnJoinedLobby のコールバックが呼び出される。
  → 以前入室していたルームに再入室する。
    同時に、プレハブ情報など、必要な情報を復元するための処置を行なう。

  上述で示したソース内容に加えると、おおまかな流れとしては、以下のように変化します。
// 上記で説明したクラスと同クラスに追記。
public class Foo : MonobitEngine.MonoBehaviour
{
    // ルーム名の退避
    string roomName = "";

    public void Update()
    {
         /*
          * 上述の内容(省略)
          */

        // ルーム名を退避する
        if( MonobitEngine.MonobitNetwork.isConnect && MonobitEngine.MonobitNetwork.inRoom )
        {
            roomName = MonobitEngine.MonobitNetwork.room.name;
        }

        /*
         * その他、gameObj の制御や、接続制御など
         */
    }

    // 途中切断されたときの処理
    public void OnDisconnectedFromServer()
    {
        /*
         * MoobitEngine.MonobitNetwork.ConnectServer を使って、サーバへの再接続を実行する(省略)
         */
    }

    // 接続完了&ロビーへの接続完了したときの処理
    public void OnJoinedLobby()
    {
        // 退避しておいたルーム名に入室する
        if( !String.IsNullOrEmpty(roomName) )
        {
            MonobitEngine.MonobitNetwork.JoinRoom(roomName);
            // ここで gameObj をリセット
            gameObj = null;
        }
    }
}


実際のサンプルとして RandomMatchingRecoonnect があります!

詳しくは、サンプルをご覧ください。

  ここまでは簡単な説明ですが、上記のままでは「再接続を繰り返し」行なってしまうため、あまりベターな方法ではありません。
  やはり「再接続するかどうか」を問い合わせるダイアログを表示するなど、サーバに余計な負荷を掛けない仕組みが必要です。

  全てを説明するには長すぎますので、詳しくは RandomMatchingReconnect のサンプルをご覧ください。