Detect other player has QUIT the application, not just disconnected
Options
Hello,
I'm trying to implement a reconnect feature to our game. It's a 1v1 game so have 2 players in a room. So far, I can detect when the player gets disconnected due to a network issue using
I'm trying to implement a reconnect feature to our game. It's a 1v1 game so have 2 players in a room. So far, I can detect when the player gets disconnected due to a network issue using
OnDisconnected()
and OnPlayerLeftRoom()
, and display a dialog while waiting for the other player to reconnect. However, I want to detect when the other player actually quits the application, and have the remaining player win immediately. Currently, I don't know of a way to distinguish whether the other player just got disconnected or has actually quit the application. Because of this, when the other player quits the application, the remaining player gets the waiting to reconnect dialog instead of winning immediately. I thought of implementing OnApplicationQuit()
, thinking I would send an event to the remaining player before the application is closed, but more often than not by the time OnApplicationQuit()
is called, Photon has already been disconnected, so I can't send events anymore. What should be the right approach to this? Thanks 0
Comments
-
Hi @dango528,
Thank you for choosing Photon!
It depends on what you mean by quit:
1. if you mean the player closed the app (or moved it to the background): you need a special event yesvoid OnApplicationQuit() { this.SendQuitEvent(); } // optional void OnApplicationPause(bool paused) { if (paused) { this.SendQuitEvent(); } } // optional void OnApplicationFocus(bool focused) { if (!focused) { this.SendQuitEvent(); } } void SendQuitEvent() { // send event, add your code here PhotonNetwork.SendAllOutgoingCommands(); // send it right now }
2. if you use PlayerTTL and you have a game logic for abandoning the game:PhotonNetwork.LeaveRoom(roomName, false)
vs. leaving temporarilyPhotonNetwork.LeaveRoom(roomName, true)
or unexepected disconnects, then you get separate callbacks for this or you can checkIsInactive
property of the player who disconnected.1 -
Hi JohnTube,
Thanks for the reply. I tried out #1, but it doesn't work because I am trying to send an event byPhotonNetwork.RaiseEvent()
to the other player and by the time I try to do that Photon has already been disconnected and the player has left the room. It gives a warning"Your event is not being sent! Check if you are in a Room and the eventCode must be less than 200", and my eventCode is definitely way less than 200. I even implementedOnDisconnected()
and the logs indicate that I got disconnected by DisconnectByClientLogic before I canRaiseEvent()
.
As for #2, I don't have a logic for leaving the room manually.
What are my options?0 -
Hi @dango528,by the time I try to do that Photon has already been disconnected and the player has left the roomthe logs indicate that I got disconnected by DisconnectByClientLogicYou should call
RaiseEvent()
before callingDisconnect()
. The player is quitting the room because a call toDisconnect()
is made somewhere in the code. Look in your own code for all calls toDisconnect()
first and putRaiseEvent()
call before it.1 -
Hi @JohnTube ,
Sorry I must have lacked some key information. I am not callingDisconnect()
manually through code, instead, it gets called automatically when I force quit the app through my device (mobile - closing the app instance) or in Unity (stopping the game in Editor). I see how if I quit the game through some exit mechanism, like an exit button or so, then I can handle the cases as usual, but that is not the case. I've also tried commenting out thethis.Client.Disconnect();
line in Photon'sConnectionStatusHandler#OnApplicationQuit()
to see if anything changes, but to no avail.
Thanks!0 -
I see.
This is rather a timing issue, a race condition of sort, or rather "script execution order" as Unity calls it.
You can try to delay PUN scripts or make your own script run first.
Then I invite @Tobias to give us his opinion about this.
How can we raise an event when the application is quitting before PUN automatically calls Disconnect.1 -
Tricky.
We disconnect on Quit, because otherwise the Unity Editor freezes. A built client typically doesn't freeze but the disconnect makes sure that anyone in a room knows quickly that this client left.
So, we want to disconnect on quit. On disconnect, the client discards any locally queued commands and sends only the disconnect on it's own.
So, to send anything briefly before this happens, you have to make sure your script runs earlier than ours. Set this up with the execution order in Unity. Also, you have to write the message (RPC or RaiseEvent) and send it right away. For the latter, use `SendAllOutgoingCommands()`.
This should work in most cases. Why just most? Because the client is still shutting down and if the message should get lost, then nobody is around to repeat it. This can't be avoided technically, unless you would wait for this message to be acknowledged (by the server, who is the receiver in this case).
Hope that helps.
1 -
Hi @Tobias ,
When you say make sure my script runs earlier than yours, what script specifically are you talking about? Since I saw theClient.Disconnect();
in Connection inPhoton.Realtime.ConnectionHandler
, I'm assuming it's that. I set the script execution order to make my script go before ConnectionHandler, but the Disconnect is still happening beforeOnApplicationQuit()
0 -
Hi @Tobias , @JohnTube
Currently we are having this limitation and our game needs it badly. We have PlayerTTL greater than 0 and have custom disconnection management where we give the player an amount of time to reconnect.
However we want to call OpleaveRoom with inactive false OnApplicationQuit.
Is there a workaround for that?
0 -
OnApplicationQuit, you can't do all that much, as the process stops more or less right away.
What you can do is to call OnLeaveRoom(false) and then SendOutgoingCommands(). Unless you have a long send queue, this will send the leave right away. But: As the app closes, there will not be a repeat should this one message get lost.0