PhotonNetwork.SetMasterClient() issue with inactive tab in browser

Options
Hi,
This topic is continuing the subject that began on the unity forum.

I got a masterClient, that is on an unselected tab, he dont update anymore to others.
When the masterClient dont update the clients send requests for being masterClient instead of the actual inactive masterClient.
The problem is, the server send a positive answer to one of the clients with becomes masterClient, but the former one, as inactive, dont get the masterClient change so he continues to act as a masterClient.

Tobias, find me a solution please. I am stuck.

Comments

  • Tobias
    Tobias admin
    edited November 2015
    Options
    As said, we can't send a message to clients which are not reacting anymore, as they are paused.

    Please try this: In the callback that sends the Master Client to background, define a new Master Client and also call PhotonNetwork.SendOutgoingCommands().
    This hopefully sends the message, before the client is actually in background.

  • Paradoks
    Paradoks
    edited November 2015
    Options
    Tobias, by saying that I dont wanted to hurt in any way, but when you say
    I can imagine how we could add such checks server-side but at the moment, it's client-side.
    it really sounds like, you could, but you dont want to.
    I understand too that you have plenty of customers asking stuffs, lots of work to do etc...
    But understand me too, i am waiting entire days on the forum for you to give me a positive answer, a solution. I am working with photon for a few years now, and i am totally stuck on this "simple" issue... Server needs to disable calls from the client that is not master anymore (if i understood what is going on).

    What do you mean by "the callback that sends the Master Client to background" ?
    If you mean my system for masterClient change, at the time i send request to change master client it is way too late, the MC is totally unavailable.

    I dont think there are moba with creeps using network non server-side , let's make it a proof of concept please.
    EDIT : :smiley: you deleted the proofs !
  • Tobias
    Options
    Unity should call OnApplicationPause() or OnApplicationFocus. I don't know which one is appropriate for your needs but it should be easy to figure out.
    In there, assign a new Master Client and call SendOutgoingCommands(), too. Hopefully, this sends the assignment to the server and other players before the connection is hibernated.
    I only see this as way to inform others about being "away" and getting some other Master Client to do the work.

    I am not entirely sure if the ex-Master Client will immediately understand that it is no longer the Master Client (because it goes to background). In worst case, PUN needs a modification for this case: Because it's effectively not communicating anymore, you could set the Master Client ID locally, without waiting for the answer of the server (which the client doesn't read anymore in BG)...

    Let us know how this works for you.
  • Paradoks
    Options
    Seems like OnApplicationPause() and OnApplicationFocus() reacts when you really lose and get the focus back, i dont work for my problem.
    I am trying to do ugly things to make it work:
    Now, after changing the masterClient ( without former masterClient knowing that he is not anymore ) i put , a TransferOwnership() with the new masterCLient in it, it almost reacts well, i mean, the new masterClient takes the control, when i switch back the former masterClient tab, creeps attacks, but dont move ... it's a kind of mess. Dont have ideas anymore.
  • Tobias
    Options
    Seems like OnApplicationPause() and OnApplicationFocus() reacts when you really lose and get the focus back
    It's not fired, when the tab goes to background?
    Sounds like a bug to me.

    Please let us know where you are at the moment. I understand it like that: Things are almost good but when the paused master client becomes active again, things go wrong?
    That sounds like you need better detect when a ex-master client returns to being active and for that, I think you need to detect when the client is paused and when it's returning from being paused.

    If some client is the master client, but paused, it should not act as master client when it returns.
    Could that help?

    I would try to modify "isMasterClient" by some "isPaused" check and maybe even with a flag "isBackFromPause". So a client is not master while in background and can clean up "isBackFromPause" before it goes on doing master client duties...

    Imho, you need to figure out the exact state of the app before you can solve the network issues.
    Can you do that?
  • Paradoks
    Paradoks
    edited November 2015
    Options
    I think you need to detect when the client is paused and when it's returning from being paused.
    In fact after detecting that, wich is pretty simple i think with a little timer, i need to find a way to "un-masterClient " the ex-masterCLient .
    If some client is the master client, but paused, it should not act as master client when it returns.
    Could that help?
    Yes
    I really think that is "only" the fact that the ex-masterClient is conflicting with the new one, i would need a way to auto-un-masterClient the ex-masterClient. is this possible ?
    Imho, you need to figure out the exact state of the app before you can solve the network issues.
    Can you do that?
    I dont have a clue how.
  • Tobias
    Options
    Again: There is currently no callback by Unity, that the app goes to background when you (e.g.) minimize the window? If this is really missing, you should file a Feature Request with Unity.

    I am unsure if a "paused" master client can assign someone else, after being paused. I fear that the moment when the app gets paused is the last moment when you can send something. I might be wrong.
    This is up to be checked: Can you send updates in background? How often is Update() being called?
  • Paradoks
    Options
    Impossible to send update in background, even the first frame when it comes.
    Seems lke update is called once per second.

    Dont know what to do anymore, I am hopless.
  • Tobias
    Options
    Do you get any callbacks from Unity that notify your game it's going to the background?
    If not, Unity might be able to add those.
    I don't know JS enough, but do also check if you could implement this in JavaScript for the browser.

    In such a callback, you should be able to assign a new Master Client.
    If we technically can't detect that a MC goes to background (and immediately stops being MC), and we can't communicate with that client anymore, then it's hard to work around all this.


    You said you already have the other clients elect a new MC, when the current doesn't send updates anymore?

    There is another way possibly but it's a bit more complex: It should be possible to modify PUN to drop incoming updates from other players, if a GameObject is controlled by the MC.
    Are you using RPC or OnPhotonSerializeView or both to sync objects controlled by the MC?

    Both types of messages pass through NetworkingPeer ExecuteRpc() and OnSerializeRead() respectively. For objects that are controlled by the MC, you could discard all updates from anyone else.

    If the old MC returns from being paused, it still needs some way to catch up. It a) needs to realize it's not the MC and b) get the current state to play on.
  • Paradoks
    Paradoks
    edited November 2015
    Options
    Do you get any callbacks from Unity that notify your game it's going to the background?
    I dont think there is anycallbacks of that kind.
    Are you using RPC or OnPhotonSerializeView or both to sync objects controlled by the MC?
    I am using both, but it seems like the one that is conflicting is the OnPhotonSerializeView.
    For objects that are controlled by the MC, you could discard all updates from anyone else.
    How ?

    how are SetMasterClient() sent ? are they buffered ?

    btw, seems like sending a buffered RPC to an unselected tab makes the games crash
  • Paradoks
    Options

    I looked everywhere, seems like i am in a dead end.
    Could you put a feature un pun please ? The one that i talked a few days back.
    You could be able to enable, lets say, PhotonView.ServersideConnectionControl(true) - or something.
    with a simple timer to know if the masterClient is still sending data, if not, dismiss it as MC and keeping track of it and telling him that he is no longer MC after he connects back ?

    I tried the photon server too and realised that i would need then to completly remake my netcode, and that my pun+ license would be useless.

    With this issue, i am about to throw 3 years of work.
  • Tobias
    Options
    We try to help you but adding some role-system (even a simple one) to Photon is quite some effort. We will have a hard time to do this quickly, so let's not yet give up on workarounds.

    I said you can discard incoming updates of users who don't control a GameObject / PhotonView.
    Did you take a look, how things work internally? You make the impression that you know how to navigate foreign code, so I would expect you to find something at least.

    I can't take a look today anymore but maybe tomorrow. I can only promise to try.
  • Paradoks
    Options
    I didn't see anything interesting in PhotonPlayer.cs and PhotonView.cs, i did not event try to look at the 3912 lines of NetworkingPeer.cs, but maybe i missed something, was looking for a stream as the isLocal is getting back to unchecked after MC change. I am banging my head on this problem since more than a month, i dont see anything anymore, and i ran out of workaround ideas...

    While asking for funny features, couldnt you make a server version run with a headless linux ? i would run it on a webServer without having to redo everything, and the result would be good, for you the work would be minimal. It would be a kind of intermediate between photon pun/server and bolt, what do you think ?
  • Tobias
    Tobias admin
    edited November 2015
    Options
    In OnPhotonSerializeView(), you could check the info parameter. How well does it work, when you skip updates that are not from the current owner (Master Client) of a (scene)view?