Need advice on relay server-client setup for long intervals between data messages

Hey all,

We’ve developed a Unity/WebGL game with Nakama using the relay server setup (one client acts as host).

We are having disconnect/timeout issues regarding how long players take to make moves.

You can think of this as similar to games that can go on for hours with large time lapses between moves, but it’s not run on a dedicated server model and that will not change.

In our setup two players connect to Nakama and start up a match (they are first-come/first-serve paired with each other). Players move their pieces and we send match data messages to coordinate this. But due to the length of the game, it is not uncommon for one or both players to pause by simply leaving the game running while they have lunch, go to class, or other activities.

To this end, we increases the socket.idle_timeout_ms to 180000 (giving us three minutes because 60000 was too short for even the average decision time on what moves to make). However, we aren’t certain that increasing this value more is the correct way to go. We didn’t understand from the given config options what else we could tweak.

And if the server setting file is not the correct place to do this, we were considering having the clients send their own match state data “heartbeat” message every 30 seconds so that server was seeing match data activity regardless of whether the players were actively engaged.

Just looking for some best practices advice here. :slight_smile:

Thanks!

Hi @AllenPDX,

If you’re using realtime socket connections, then socket.idle_timeout_ms` may not apply, what can increase tolerance for socket disconnection is increasing the [socket.ping/pong_period_ms](Configuration - Heroic Labs Documentation.

However, increasing these values to be very high also means that the server may detect actual disconnections (due to network disconnects or issues) very late.

There’s an alternative RPC driven approach that you could take to minimize this issue, loosely following these steps:

  1. matchmake players
  2. put them in a “match” that’s not really a match, maybe just a storage object and a few RPC functions
  3. players send moves by calling an RPC, which applies some rules maybe and just writes the move to the storage object
  4. if the opponent is online, send them a custom in-app notification that a move was done (so no polling is needed)
  5. if the opponent is not online, when they next start up the game check their running matches for progress
  6. after some length of time delete “old” inactive matches via CRON

Hope this helps.

Thanks for the response!

The game has no real-time interaction between players since it may be used in locations that have poor internet speed. When one player is moving their pieces during their turn, the other player gets a “opponent is deciding their move” banner and is locked out of changing anything that would alter the game board state, so they will not send any kind of match data while they are idle. When the active player has moved as many pieces as allowed they click submit, the message state data is passed to the other player to update their board, and then it’s their turn to move while the other player waits.

So this also ends up with long gaps where neither player is sending match data even if both players are actively engaged with the game. The game specs did not want a time limit for the players to make their moves.

When I was testing recently, I found that when I took longer than 1 minute the server received my match data update message, but the waiting player never received the message even though they had not dropped their connection (according to the logs). Increasing the socket timeout value to three minutes fixed this issue going up to three minutes, which initially led us to thinking that would be all we had to do. But that doesn’t feel right. There seemed to be a discrepancy between an actual socket disconnect and the match treating an idle player as “stale”(?) and no longer able to receive match data messages.

I’m not sure if that helps clarify the problem, but that is why we were considering a heartbeat message.

-A