Closed uladzislaubasin closed 3 years ago
This isn't something we can fix...the device killed the connection.
@MrGadget1024, what about reopening the connection in such case?
Yeah some devices handle this differently, minimising on PC usually keeps game open and running, Android freezes game but keeps connections, Apple tends to freeze the game and kill the connection like Gadget said.
"what about reopening the connection in such case?" You would handle this manually, theres a Unity OnApplicationResume, or OnApplicationQuit, or OnApplicationPaused use these to reconnection to a saved ip/port of previous host. :) @uladzislaubasin
Just to add onto MrGadget's comment:
Run in background is patchy on mobile, because Unity requests said permission to run in the background on mobile OS. However, it is up to iOS or Android to allow said permission. It may be denied due to configuration or system state.
Some custom versions of Android like Samsung's Android variants may also have a battery optimizer system that kill inactive programs aggressively. There's nothing we can do about that. We have zero control over what the mobile operating system does with its processes. Usually on iOS you get a very short period of time to handle the suspension of the application (10 - 15 seconds), on Android it can be immediate or delayed.
About reconnecting - that's up to you to implement. Maybe if you detect a unclean shutdown of the connection or disconnection then you attempt to reconnect and deal with it that way. Mirror is not designed to auto-reconnect but it is possible to implement said mechanic.
TL;DR: Nothing us Mirror developers can do. Implement a reconnection mechanic yourself or deal with the disconnection. There is a reason why Android/iOS can be a thorn in a devs' backside, and this "connection dying when minimized" is one of them.
EDIT: Consoles do this too. Nintendo Switch is known to cut communications when you press the home button as it "suspends" the application in use.
@JesusLuvsYooh @SoftwareGuy the problem is that Mirror automatically destroys all player related resources. Because it treats that as disconnect BY USER, rather than waiting for a timeout specified in transport. And disconnected player simply disappears. This is a way for cheating. E.g. if you are in a complex situation, simply minimize the app and then activate it again, because next time connecting Mirror will spawn you elsewhere (player spawn location).
Is there something already in the library we can use that may keep player related objects for some time to be able to connect again? Otherwise, we have to save player state, create a "ghost" that correspond to disconnected player so that other players can interact with it. And once player is connected we should restore the state while replacing the ghost. This need sounds very complicated and bugs vulnerable.
There will be many ways you can handle this, however it is not upto Mirror to do this, you can detect it and add yourself. One way could be a punishment system, if they leave when they shouldn't do, or don't press quit, logout, and go back to menu, etc Spawn them back with 50% health and magic, nerf their arse XD
I show an angry message if they do this in one of my games, along with the health and magic nerf.
It also doesnt save some of their progress, such as XP earnt, but once again, all for you to do as you please.
My personal opinion (I may be wrong) is that destroying Player object after disconnect is not a good design choice for a modern multiplayer library, because nowadays users expect the ability to reconnect smoothly. Especially on mobile devices, when the connection may not be 100% stable.
Nevertheless, I have extended Mirror library so that Player resources are not destroyed after disconnect and they can be reused if the user connects again.
I may create PR for review to introduce this functionality as out-of-the-box for Mirror. Let me know if you are interested.
My personal opinion (I may be wrong) is that destroying Player object after disconnect is not a good design choice for a modern multiplayer library, because nowadays users expect the ability to reconnect smoothly. Especially on mobile devices, when the connection may not be 100% stable.
I disagree. Why should the server have a slot occupied waiting for a disconnected player to reconnect, when if you disconnect because your connection shat itself or Android/iOS got an incoming call and minimized your game? Too bad, let someone else take your slot that you were previously occupying. Sure, on mobile it can hurt the experience if someone checks a text message and the game disconnects because of that.
Some UDP-based protocols will "persist" the connection for some time, I remember when I was testing Tanks with Ignorance that it would synchronize up after a 3 - 5 second minimized period. If the client can sync back up then well that's fine and dandy.
Nevertheless, I have extended Mirror library so that Player resources are not destroyed after disconnect and they can be reused if the user connects again.
I may create PR for review to introduce this functionality as out-of-the-box for Mirror. Let me know if you are interested.
By all means do so, or make it into a module/component that handles this behaviour, be it session tokens or whatnot. We'll give it review and if it doesn't make it into the core then you can still let others know that a solution does exist and you can offer them your solution.
IMO, this is considered a "luxury" feature. But I can see the use in it, some games like World of Warships Blitz on mobile that use Unity Engine do have a grace period (even the desktop version that uses BigWorld Game Engine) before they mark you as ghost user/disconnected.
Hello, @uladzislaubasin. How are you? I am interested in your code. If you still have it, I would be very grateful if you post it. What I am trying to archieve is the following: My game is some kind of battle royale shooter and when a player disconnects I would like to keep the player game object still in the scene waiting for the user to reconnect. In that time, if the player reconnects can take the control of the player again where it was before disconnecting (In the mean time the player can be killed by other players). and if the player does not reconnect after 30 seconds set the player as killed and removed. Would your solution be suited for this case?
Thanks in advance
Describe the bug When you switch the app onto another one on iOS\Android and then come back, you get disconnected from the server. The same thing happens when you turn off Wi-Fi and the system quickly switches you to 4G internet. NOTE: this happens even when NetworkManager setting runInBackround == true.
How to reproduce the issue, step by step Reproducible with KCP transport on iOS\Android for all related examples.
Expected behavior KCP transport has a timeout property. In case of internet connection is lost for a shorter period, the client must NOT be disconnected.
Desktop (please complete the following information):
Additional context I believe that this happens because once you lose focus on the app, iOS\Android pauses it and Mirror does not properly handle resume.