I’m testing my multiplayer game using relay and the connection seems to drop out pretty regularly after a minute or so of playing. It seems to happen more often and faster if only the host is playing. Has annoying else experienced this? How do I prevent it?
Are you sure the relay drops? I will say by default connections do seem to be dropped after a while but you can send a tiny data post as a ping to make it more in your control. So you could test to see if player afk and then if afk longer than x disconnect them.
There is also documentation about how somethings do close if not used.
Got any more info?
Can you describe what actually happens? Did you check for errors (exceptions) in the console/log?
@CodeSmile @bugfinders This is the exception:
Host is shutting down due to network transport failure of UnityTransport!
Transport failure! Relay allocation needs to be recreated, and NetworkManager restarted. Use NetworkManager.OnTransportFailure to be notified of such events programmatically.
It’s those “little things” that make networking so complex. You’d think that Start/Stop networking is just that: start and stop, and for the client also the connect/disconnect events.
Alas, here’s the Statemachine for this very basic flow that I had to create to account for all the potential events at every stage:
Note that “Is…Started” also becomes false on a transport failure, so that’s already handled in place.
Also note the “shutdown” state at the end which waits for shutdown to be complete before you can restart a network session. For the server shutdown is not instant.
Interesting chart but I’m not sure how that helps me!
Are you saying I just need to restart the host when the network drops?
Is this a common problem with relay? Using standard Unity transport I haven’t had this issue. Would dedicated servers be more stable?
I’m saying: don’t leave “error” events unhandled. These are valid paths in the application.
So if transport fails, this will effectively call NetworkManager.Shutdown(). However if the app isn’t prepared to suddenly have a NetworkManager that’s “offline” then you will likely run into a subsequent, seemingly unrelated issue such as NullReferenceException for instance when accessing NetworkManager.SceneManager.
And since shutdown isn’t instant for server/host you also need to check if the NetworkManager is truly offline before starting a new session. I use this to check offline state:
public Boolean IsOffline()
{
var net = NetworkManager.Singleton;
if (net == null)
return false;
return !(net.ShutdownInProgress || net.IsListening || net.IsServer || net.IsHost || net.IsClient);
}
There may or may not be similar “failure” events for Relay that need to be handled accordingly.
I see what you’re saying, I should handle the drop and recreate the connection. But wouldn’t that interrupt the game? Ideally I’d like to prevent the drop, I don’t know why it’s happening.
I’m handling the OnTransportFailure just by displaying an error message currently. I’ll try restart the relay allocation and keep the lobby alive so I can send out the new join code… but this seems like a band-aid fix to a problem with relay.
private void Start()
{
//Check if we can start already (solo player)
CheckIfCanStart();
if (CurrentState.Equals(GameState.WaitingForPlayers))
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
NetworkManager.OnTransportFailure += OnTransportFailure;
}
private void OnTransportFailure()
{
ErrorUI.Instance.ShowError("Network Error", "Connection Failed", "Check your internet connection and try again");
}
What region are you in? Do you use VPN?
The relay service by default uses QoS to provide you with a server near your region. But you can also hand-pick a relay server I believe, I had stumbled across this in the manual a few days back. You could try your luck there if you happen to have a bad connection to that particular region’s relay server.
You may also want to dig deeper in the transport layer to see why that failure occurs. Perhaps you’re simply sending too much data all at once or something like that.
I’ll try this and also try a cut down project to see if I can replicate. I’m using “best” which it defaults to Australia se
Turns out I had 2 issues - the client was loading the scene also, meaning occasionally they would load 2 scenes, causing a bunch of issues. Using NetworkSceneManager it automatically loads the client now (didn’t know it did that, the code I had sampled made the host AND the client load the scene).
Also because my scene takes a while to load, it would sometimes lose the connection. I addressed that by having a “staging scene” load first, then the main scene is loaded additively.
Been testing quite a bit and haven’t encountered the issue again.
