How to Switch Master Client?

Good day,

My biggest issue before putting out my android game is now related to the master client putting the app into the background, or disconnecting.

The game looks "paused" or the other players get disconnected automatically.

I don't really understand how to switch the masterclient, along with the objects that it instantiated.

How would I tackle this problem?

Comments

  • JannickL
    JannickL
    edited December 2016
    @Pav If a client leaves a room all his instantiated objects will get destroyed.
    The MasterClient switches automatically when he leaves.
    Use photon network instantiate scene object instead of the normal PhotonNetwork.Instantiate.

    Notice that only the masterclient can change the transform of those scene objects but they will not get destroyed when the mc leaves or a another player becomes the mc.

    Greets
  • Ah, I see.
    I did a lot of searching before I put up this question, wasn't aware that the master client switches automatically if that player leaves.

    What about cases regarding having the app in the background?
    Or it'll be fine as long as I use networkinstantiate scenebject
  • @Pav Check out if the player stills sends data when the app is backgrounded. If the player stays connected and sends data you will not have a problem. Btw unity got a allow background settings but i don't know if it works with mobile too.
  • I tried "PhotonNetwork Instantiate Scene Object" but because it has a photonview for transform, it's frozen when the masterclient is running the app in background.
  • Pav
    Pav
    edited December 2016
    I see. That doesn't work with android unfortunately, but I figured out how to determine if the masterclient is paused. https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnApplicationPause.html

    However, I haven't played around with getting photonPlayer ID's and I'm stuck at..

    PhotonNetwork.SetMasterClient(PhotonPlayer);
  • Alright. I got it to switch masterclients, but it doesn't work properly.

    When current masterclient puts the app into background, it doesn't transfer. Only transfers when the app comes back into focus.
  • @JannickL Ok, it works properly now, How could I choose the the next playerID to be the master client? so far I just do..

    PhotonNetwork.SetMasterClient(PhotonNetwork.playerList[1]);
  • JohnTube
    JohnTube ✭✭✭✭✭
    @Pav @JannickL

    ICYMI: there is a documentation page about "Master Client and Host Migration".
  • @JohnTube I've seen that, and it makes sense. I've made a script that switches the masterclient, however, it's based on OnPhotonSerializeView.

    Would you suggest doing PunRPC instead?
  • JohnTube
    JohnTube ✭✭✭✭✭
    @Pav
    I'm not a PUN expert. I'm used to plain Photon events (RaiseEvent).
    My other colleagues are on vacation so I can't ask them now.
    But IMO, PunRPC is better than OnPhotonSerializeView.

    In any case I think you should switch the MasterClient from another client that detects the MasterClient disconnection and use this:
    
    PhotonNetwork.SetMasterClient(PhotonNetwork.masterClient.GetNext());
  • @JohnTube That works even better than what I had. Appreciate it :)
  • wtdunity
    wtdunity
    edited February 2018

    *******Best Working way to change Master Client in photon network.******
    void OnApplicationPause(bool pauseStatus)
        {     
    
            if (pauseStatus)
            {
                if (PhotonNetwork.connectionState == ConnectionState.Connected && PhotonNetwork.inRoom && PhotonNetwork.isMasterClient)
                { 
                    // Game is in Background | pause | quit
                  
                    //PhotonNetwork.BackgroundTimeout = 2f;                                                
                    ChangeMasterClientifAvailble();
                    PhotonNetwork.SendOutgoingCommands();
                   
                }
            }
            else
            {
               
                if (PhotonNetwork.connectionState == ConnectionState.Connected && PhotonNetwork.inRoom && PhotonNetwork.isMasterClient)
                {                
                   // do whatever you want . if you not reach time to live player then you are connected and inroom already.
                }
    
                //check if game end ||room destroyed ||timeout
            }        
        } // End OnApplication Pause.
    
       
       /// <summary>
       /// Changes the master client if availble.
       /// </summary>
        public void ChangeMasterClientifAvailble()
        {
            if (!PhotonNetwork.isMasterClient)
            {
                return;
            }
            if (PhotonNetwork.room.PlayerCount <= 1)
            {
                return;
            }       
            
            PhotonNetwork.SetMasterClient(PhotonNetwork.masterClient.GetNext());                 
        }
    
    
     public virtual void OnMasterClientSwitched(PhotonPlayer newMasterClient)
        {
     //event will fired to all connected players in same room.
    //if master client goes in background then new master client info hear. 
    }
  • illogical
    illogical
    edited January 2020
    Hi, i am using this method. could it be any better? or am i doing it wrong?
    float lagTimer;
    
    void Update()
    {
        if (PhotonNetwork.IsMasterClient)
                {
                    lagTimer += Time.deltaTime;
                    if (lagTimer > 1)
                    {
                        lagTimer = 0;
                        this.photonView.RPC("CheckNetworkLag", PhotonNetwork.MasterClient.GetNext());
                    }
                }
                else if (PhotonNetwork.LocalPlayer == PhotonNetwork.MasterClient.GetNext())
                {
                    lagTimer += Time.deltaTime;
                    {
                        if (lagTimer > 2)
                        {
                            lagTimer = 0;
                            PhotonNetwork.SetMasterClient(PhotonNetwork.MasterClient.GetNext());
                        }
                    }
             }
      }
          
            [PunRPC]
            public void CheckNetworkLag()
            {
                lagTimer = 0;
            }
    
  • As I understand the masterclient is automatically switched by photon on current mc got disconnected. You just have to setup plugin properly.
    And the problem was with an app going to background, and in that case you should use OnApplicationPause/Focus to check if you are mc and tell others you are about to go to background via rpc.
    I'm not an expert, so its just things to think about )
  • Hi @Djebedia thanks for your response. However the OP is 4 years old. I am sorry i had to resurrect it.

    what do you think of my code above? is it good idea to check latency using RPC? I am following the idea of "heartbeat" in this photon documentation here

    I dont think of any other method but correct me if im wrong
  • JohnTube
    JohnTube ✭✭✭✭✭
    I have answered here.
  • I'm looking if there's a way to set another player to Master Client during game.