OnPhotonPlayerDisconnected not called after Disconnect() ?

Options
Hi guys,

I just spent a lot of time trying to figure out why my OnPhotonPlayerDisconnected was not called after the PhotonNetwork.LeaveRoom() on one client, and after 6 depressions and 12 reconsiderations of my career, I discovered that this callback is not called when the disconnected client executes a PhotonNetwork.Disconnect() after the PhotonNetwork.LeaveRoom().
Is this behavior intended ?

Comments

  • PyeNog
    Options
    Hi,
    Have you tried to test it with 2 or more players? (you can do this locally, just execute one more your game)
    That callback is called when other(remote) player is disconnected, not your local player.

    Hope my answer is helpful to you.
  • Hi,
    Sorry to resurrect this thread, but I actually still need help. I think I missed your answer, PyeNog, sorry about that.
    Of course, I tried it with 2 players. The weird behavior is the following : We have 2 players, let's say A and B who are in the same room.
    - When A calls PhotonNetwork.LeaveRoom(), and only that, B gets the OnPhotonPlayerDisconnected callback. Problem is I'd like to make A disconnect from Photon server.
    - When A calls PhotonNetwork.Disconnect(), and only that, B does NOT get the OnPhotonPlayerDisconnected callback. It is a little bit inconvenient, but maybe it is intended (I find this weird though...).
    - When A calls PhotonNetwork.LeaveRoom() then PhotonNetwork.Disconnect(), B does NOT get the OnPhotonPlayerDisconnected callback either. It is very inconvenient, because I can't find a way to make A leaves both the Room and the Photon server AND B gets the OnPhotonPlayerDisconnected callback...

    I tried another solution too :
    - A calls PhotonNetwork.LeaveRoom();
    - A gets the OnLeftRoom callback and calls PhotonNetwork.Disconnect() in it
    It did not work either, I get a console message : "Can't execute Disconnect() while not connected. Nothing changed. State: DisconnectingFromGameserver". Then A is still connected to Master, which I don't want to.

    Help !!!
  • Hi @AlexKhundar,

    Sorry to resurrect this thread


    No problem. I'm sorry for the very late response. I somehow didn't notice this thread.

    I quickly created an Unity application to test this scenario myself. All three scenarios I used are working as expected for me. These are PhotonNetwork.LeaveRoom();, PhotonNetwork.Disconnect(); and the combination of both of them whereat the the disconnect function gets called from the OnLeftRoom() callback.

    While creating this test I noticed that I run into problems with enabled autoJoinLobby option. after disabling this option and reworked some callbacks, it worked as already mentioned above. Do you have the autoJoinLobby option enabled?

    Since the original question is already some months old, which version of PUN are you currently using? Have you updated PUN in the meantime to a later version?
  • Hi @Christian_Simon, thanks for your help.

    autoJoinLobby option is disabled and hopefully it will always be. So, I think we don't need to worry about that.
    When you tested the three scenarios, was the OnPhotonPlayerDisconnected callback called in remote player ? In every scenario ?

    I'm using PUN v1.81. I was afraid to update PUN since the first time I integrated it on my project (on April 2017, I guess), so I never did. Is it safe to update ?
  • Updated this morning to v1.87, did not fix the problem. I myself created a quick Unity application which does approximately the same work as my real app. The bug is here too. Here's a link to a WeTransfer if you want to test it (there's just one script and one scene, get Photon to test it) : https://we.tl/XgN9OYkdCA

    Otherwise, the source code is following.

    In this example, the room is automatically joined when the player joins MasterServer. And when the room is left, I'd like the player to be totally disconnected from Photon. To be clear, a player is never in the MasterServer during a longtime. He immediately goes in the room when connecting MasterServer, and when he leaves the room, he must be disconnected from Photon.
    public class MyScript : Photon.PunBehaviour {
    
        public void OnClickConnect()
        {
            ConnectToPhoton();
        }
    
        public void OnClickDisconnect()
        {
            PhotonNetwork.LeaveRoom(); /// With only this line, local player will leaveRoom and join MasterServer, which I don't want. (In this example, he will reconnect to the room)
            PhotonNetwork.Disconnect(); /// With only this line, local player will leave both room and MasterServer BUT <see cref="OnPhotonPlayerDisconnected"/> callback won't be called on remote player
            /// With both of the lines, same as only 'PhotonNetwork.Disconnect()' call : local player will leave both room and MasterServer BUT <see cref="OnPhotonPlayerDisconnected"/> callback won't be called on remote player
        }
    
        void ConnectToPhoton()
        {
            string name = Application.platform == RuntimePlatform.WindowsEditor ? "editor" : "standalone";
            PhotonNetwork.AuthValues = new AuthenticationValues();
            PhotonNetwork.AuthValues.AuthType = CustomAuthenticationType.None;
            Debug.Log("Attributing Photon userID : " + name);
            PhotonNetwork.AuthValues.UserId = name;
            PhotonNetwork.playerName = name;
            PhotonNetwork.ConnectUsingSettings(Application.version);
        }
    
        public override void OnConnectedToMaster()
        {
            Debug.Log("ConnectedToMaster : " + PhotonNetwork.player.UserId);
            PhotonNetwork.JoinOrCreateRoom("roomTest",
                new RoomOptions() { MaxPlayers = 2, PublishUserId = true, PlayerTtl = -1, IsVisible = false },
                TypedLobby.Default);
        }
    
        public override void OnJoinedRoom()
        {
            Debug.Log("OnJoinedRoom : success");
        }
    
        public override void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
        {
            Debug.Log("PhotonPlayer entered the room : " + newPlayer.UserId);
        }
    
        public override void OnDisconnectedFromPhoton()
        {
            Debug.Log("Disconnected from Photon");
        }
    
        public override void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
        {
            Debug.Log("PhotonPlayer left the room : " + otherPlayer.UserId);
        }
    }
    
  • When you tested the three scenarios, was the OnPhotonPlayerDisconnected callback called in remote player ? In every scenario ?


    Yes, worked in all scenarios.

    The problem here is setting the PlayerTtl value to -1. When removing this value or setting it to a 'normal' value, the OnPhotonPlayerDisconnected callback will work as expected. Is there any reason why you want to never timeout a client for the lifetime of the room?

    Some other hint: calling LeaveRoom and Disconnect directly after each other might work, but you can think about adding the OnLeftRoom callback and use this one in order to disconnect from Photon. So basically when you call LeaveRoom, OnLeftRoom will be called afterwards. From this callback function you can use Disconnect to - obviously - disconnect from Photon.

    Hope that helps.
  • AlexKhundar
    edited November 2017
    Options
    The problem here is setting the PlayerTtl value to -1. When removing this value or setting it to a 'normal' value, the OnPhotonPlayerDisconnected callback will work as expected. Is there any reason why you want to never timeout a client for the lifetime of the room?

    There is, it's about the design of the game. It's a "board game", with only two players, and when a game is started, I don't want anyone to join the room, except the two originals players. Furthermore, I'd like to handle network issues and allow a disconnected player to come back in the game. I'm using PhotonNetwork.RejoinRoom(roomName) to do that, and it works very fine. My only issue right now is about the OnPhotonPlayerConnected callback.
    But is there any reason why the PlayerTtl value set to -1 causes this ? It looks like a bug to me. It seems very strange that calling just a LeaveRoom triggers the callback but calling a Disconnect just after the LeaveRoom does not.

    Some other hint: calling LeaveRoom and Disconnect directly after each other might work, but you can think about adding the OnLeftRoom callback and use this one in order to disconnect from Photon. So basically when you call LeaveRoom, OnLeftRoom will be called afterwards. From this callback function you can use Disconnect to - obviously - disconnect from Photon.

    I talked about this in my 2nd message of this thread. I tried it, but there was a warning message in the console, and it did not work better... (Quote following is what I said about it on my 2nd message)
    I tried another solution too :
    - A calls PhotonNetwork.LeaveRoom();
    - A gets the OnLeftRoom callback and calls PhotonNetwork.Disconnect() in it
    It did not work either, I get a console message : "Can't execute Disconnect() while not connected. Nothing changed. State: DisconnectingFromGameserver". Then A is still connected to Master, which I don't want to.
  • JohnTube
    JohnTube ✭✭✭✭✭
    Options
    Hi @AlexKhundar,

    In current PUN here is how it works:

    Inside rooms created with PlayerTTL != 0:

    1. If you call PhotonNetwork.LeaveRoom(), the actor will leave the room and will be removed from its actors list then it will disconnect from Game Server and connect back to Master Server. On the other joined clients the following callback will be triggered:
    void OnPhotonPlayerDisconnected(PhotonPlayer remotePlayer).
    "Disconnected" should be understood as "Left" here.

    2. However, if you call PhotonNetwork.Disconnect(), it will disconnect the local client from ALL photon servers and not just the Game Server where the room exists. The actor will be marked as INACTIVE inside the room and on the other joined clients the following callback will be triggered:
    void OnPhotonPlayerActivityChanged(PhotonPlayer otherPlayer).
    otherPlayer.Inactive should be true.
    If PlayerTTL != -1, if any other actor stays joined for PlayerTTL milliseconds, another callback will be triggered because the remote inactive actor will time out and will be removed from the actors' list. I'm not sure which callback though in this situation, it should be void OnPhotonPlayerDisconnected(PhotonPlayer remotePlayer).

    Inside rooms created with PlayerTTL == 0 (default):

    No matter if you call PhotonNetwork.LeaveRoom() or PhotonNetwork.Disconnect(), the actor will leave the room and will be removed from its actors list then it will disconnect from Game Server and connect back to Master Server. On the other joined clients the following callback will be triggered:
    void OnPhotonPlayerDisconnected(PhotonPlayer remotePlayer).
    "Disconnected" should be understood as "Left" here.
  • Hi @JohnTube,

    Thanks for your help !
    It seems that the OnPhotonPlayerActivityChanged callback is my savior. However, I can see in the documentation that it is called "when a remote Photon Player activity changed". Is there other situations than a disconnect in which the activity of a player could change, which would trigger this callback ? Maybe network issues ? I could't find this. Futhermore, if I may, the documentation has a little mistake. It says that OnPhotonPlayerActivityChanged is called only if PlayerTtl is greater than 0. As you said and as I can confirm with my tests with PlayerTtl set to -1, it is if PlayerTtl is different than 0.
    Anyway, quick tests make me think my problem could be solved with this OnPhotonPlayerActivityChanged callback, which is very good.

    Thanks a lot !