Host migration logic

Options
According to this recommendation here on the host migration documentation.
If your Master Client is constantly sending events in the room, you can implement a Master Client timeout detection mechanism by saving timestamp of last event received from Master Client and checking that value constantly in your game loop. When you detect that the Master Client is not sending events as expected you can then switch Master Client explicitly. The tricky part is to choose the timeout value. A low value may give false positives and make the Master Client switch happen too often. Also a choice needs to be made on whether this check needs to be done from a single actor (next Master Client candidate maybe) or all actors.

so what do you think of my code? is it good? or can it be better?
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;
        }
        public override void OnMasterClientSwitched(Photon.Realtime.Player newMaster)
        {
            if (newMaster == PhotonNetwork.LocalPlayer)
            lagTimer = 1;
            else if (PhotonNetwork.LocalPlayer == PhotonNetwork.MasterClient.GetNext())
            lagTimer = -3;
        }

Comments

  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @illogical,

    Thank you for choosing Photon!

    It could work yes.
    But of course, your tests should validate this.

    I wanted to suggest a little optimization/improvement.
    Since you are using RPCs, you could make use of the send timestamp:
    [PunRPC]
    public void CheckNetworkLag(PhotonMessageInfo info)
    {
          double sentTimestamp = info.SentServerTime; // compare/diff with PhotonNetwork.Time
    

    This way you can calculate since when the master server sent its last hearbeat RPC.
    The good thing about all this is that you use a network synchronized clock handled by PUN.

    Other suggestions:

    - make the solution flexible: the timeout values for sending or switching should be configurable on the fly from the editor or via code (instead of hard coded values, 1 or 2, make them fields/properties). It helps to quickly fine tune when prototyping.
    - send the event to everyone, this way you can avoid a situation when the next master client drops between events and you always have the most up to date candidate with the proper values.
  • illogical
    Options
    @JohnTube Thanks for your response
    - send the event to everyone, this way you can avoid a situation when the next master client drops between events and you always have the most up to date candidate with the proper values.

    sorry if this is a noob question. isnt sending to everyone consume more msgs?
    [PunRPC]
    public void CheckNetworkLag(PhotonMessageInfo info)
    {
          double sentTimestamp = info.SentServerTime; // compare/diff with PhotonNetwork.Time
    

    compare the sentTimestamp to what?

    Thanks!
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited January 2020
    Options
    @illogical

    save the timestamp locally.
    instead of
    if (lagTimer > 2)
    

    do (example)
    if (PhotonNetwork.Time - lastSavedTimeStamp > masterClientHearBeatTimeout)
    

    and to reset, instead of
    lagTimer = 0;
    

    do
    lastSavedTimeStamp = PhotonNetwork.Time;
    
    
    isnt sending to everyone consume more msgs?
    Yes of course. But I think if you send every X second(s) N messages it's OK.
  • illogical
    Options
    great. Thanks for you input!