Cannot return to a game

I think up to last week there was no problems on reconnecting temporarily disconnected players to a room. But now every time a player attempts to rejoin a room using same actorID, it fails with error message
Join failed: actornr=xx already joined the specified game.

So I tried to run our last week build to see if it runs normally (no problem on rejoining a room) we can conclude there is something wrong in our codes, but players still can't rejoin a room. Did something happen to the server/API?

Related API:
http://doc-api.exitgames.com/en/turnbased/current/dotnet/doc/class_exit_games_1_1_client_1_1_photon_1_1_load_balancing_1_1_load_balancing_peer.html#a694312512d95b276080f232699a6ae68

PS: we use the latest Photon Turnbase Unity SDK 4.0.0.4

Comments

  • Check if the code for rejoining a game is not executed more than once, as Photon receives "replicate" Operations ACKs and their respective "replicate" Events (some are associated with GameServer and others to NameServer; Photon broadcasts "everything" to all actors in a room; there may be multiple Operation ACKs and Events for a single Operation).

    One more thing, do you explicitly set CheckUserOnJoin option to True when creating a Room in the two builds ?
  • Yes, CheckUserOnJoin is set to True in both builds.
  • I just checked my code and test if any LoadBalancingClient's Op* functions got executed twice or more but there was no such problem. Now I'm really lost.
  • There was no changes in server api

    all what we could advice is check revision by revision, then you will find revision where bug was introduced
  • Can you test with CheckUserOnJoin set to false?

    Can you elaborate on the timing of your case? How do you disconnect the client and how fast do you try to return to the game?
    The client must use the same userID as before and in the room, the user must be inactive in the room.
    In worst case, the server did not notice that the client disconnected (it's a connectionless protocol with a timeout algorithm if messages no longer get acknowledged). So it's possible that a client tries to re-connect before the server notices that this user was gone at all.

    A timeout should take no more than 10 seconds. Maybe you can re join after that time?
  • As said, it might be a timing related issue which you didn't notice before.
    You can try to let your clients call Disconnect() when they close or go to the background. We attempt to send it before the client execution stops and it will disconnect you in most cases immediately.

    I debugged my code throughly and tried to find any possible cause. Here is what I found and it's quite complicated:

    - This problem (can't rejoin to a game) always occur in iOS (and Android but not always), when I put the phone to sleep while the app is in the foreground then resume the app from lock screen while the phone is being CONNECTED to the internet. It doesn't matter what the state of the connection is before putting the phone to sleep.

    - The problem doesn't occur from any other actions that make the app disconnected from Photon (switching network mode or to airplane mode, putting the app to background mode, etc). The player can rejoin to the room normally if I resume it from sleep mode while being DISCONNECTED from the internet, and then connect the internet later after the app is in the foreground.

    - I tried to reproduce the problem by making a new project that contains only Photon Turnbased SDK and small codes to handle room creation, join, rejoin, but all players can always rejoin without problem.

    - I just tried your suggestion to call Disconnect() right after the phone is put to sleep mode, and problem solved!! :)

    Still don't know what exactly caused the problem, but at least players can now rejoin their game. So I got that going for me, which is nice. Thanks for the help!
  • If you couldn't reproduce the issue with a minimal test project, then it I would take another look at where in your game-state things might get stuck or disconnect or do unexpected things. Sometimes its a simple script that runs in unexpected cases...

    Take a close look at what we log in the console. In doubt you can raise the debug level and see if you can get more info. Unity is nice and prints the callstack every time, which often gives you an idea where the issue comes from.

    If you can't find a solution or think it's a Photon issue, let us know in a fresh thread. We will definitely take a look.
  • What Operation in the LoadBalancingClient should I exactly use to Rejoin a Game/Room ?

    There are two different scenarios :

    - The Room is still in Photon servers : JoinMode should be Rejoin ?
    - The Room was removed from Photon servers after all players left (and if LobbyType.AsyncRandomLobby, the RoomTTL=1h expired) : JoinMode should be CreateIfNotExists ?

    What's more confusing is the existence of JoinMode and JoinType ! What's the difference between the two ? I don't see where the two values are used together, as I understood from the API docs, one of the enums was introduced "just" to replace the createIfNotExist bool. The other difference I spotted is that JoinType is only used in LoadBalancingClient while JoinMode is "internally" used in LoadBalancingPeer.

    For instance the overload OpJoinRoom in LoadBalancingClient with the following signature :
    public bool OpJoinRoom(string roomName, int actorNumber)
    
    Has the following summary : Joins a room by name and sets this player's properties. Optionally, a room can be created if not existing already. Which I found absurd as later int the remarks you can read If the room is not existing, JoinRoom will also fail by default. I guess this was a copy/paste. Anyway, I looked into the LoadBalancingPeer.OpJoinRoom called inside and I've found out that if an actorNumber is set (different than 0) the JoinMode is set to Rejoin and on the other hand the createIfNotExist is set to false.

    My question is the following, the Rejoin mode expects the webhooks to be configured and working in order to load the game state ? In that case, I want to know what can be saved and restored to the Room. Is there any chance, events can be re-used : saved and loaded ?
  • Sorry for being so confusing.
    The JoinType was really planned to be used internally. When you join or create a room, the client has to switch to another server. It disconnects and basically repeats the required operation on the GameServer. For that, we have the JoinMode. Of course it could be done more elegantly. As always.

    The JoinMode is what we use in the Operations: Default, CreateIfNotExists, Rejoin. The ReJoin is used when we want to find a game that's potentially saved (not in memory). It's usage is currently a bit messy (this much is obvious) and the plan was to hide it entirely. Initially you were required to send the ActorNumber that the player had in the room before. With Custom Authentication this usage is less important as the server now checks the userID when you use one (which is the best practice).

    The description for OpJoinRoom() is totally wrong. Most likely a copy and paste bug. Thanks for pointing this out. I will take care of a proper description and there should be an update soon. The optional part comes from OpJoinOrCreateRoom(), which is good when players invite each other and you're not sure if someone invited might beat you to creating the room.


    About the state: Any Custom Property and all Buffered Events are stored automatically with the game and will be sent to re-joining players when they return. As with late-joining players, this is what the client gets first.
    So anything State-related has to be buffered or a property.

    See:
    http://doc.exitgames.com/en/turnbased/c ... e-overview
    http://doc.exitgames.com/en/turnbased/c ... emory-demo