0

I am struggling to make my own matchmaking in a multiplayer game of two players. I have a button that says "play",and i want if the user presses it to change in database his schema property "inQueue to true" .

So after that i want to search the database to check who also is online and in queue(and meets requirement range for elo eg. player1:1200 ELO player2:1288 ) . But i dont want to send multiple requests until it finds a match.

iI was wondering if is there a way to send the request one time and when mongodb finds a match then return the response. ( i am using the mern stack with the help of sockets too)*

sample of database schema

  • please read the guide, how to ask a good question at stackoverflow -https://stackoverflow.com/help/how-to-ask – Gulshan Aggarwal Jun 11 '22 at 15:10
  • you might be better with some kind of socket transmission ([web sockets?](https://stackoverflow.com/q/10112178/28004)), so you add the message that a new user is in Queue, and your service waits until another message is received and matches... once matched, then write to the database player1 vs player2 and the start of the match as a log for example – balexandre Jun 11 '22 at 15:12
  • @balexandre yeah that is true i have thought of that way but as you see a have an elo property on my Schema . So i want to make the match only if it meets the requirements (+- some elo range) – Μελέτης Πέππας Jun 11 '22 at 15:22
  • you can have all that, separate your Match Making, for example, make it your Socket Message Queue, soon you have a new player in queue, call the db and populate with the data you need to match against another player. Remember that reads are super fast, it's when you write that takes a bit more time, so, to read and populate your MM with queue players, should not be an issue – balexandre Jun 11 '22 at 15:37
  • @balexandre thanks a lot for your insights i will try doing it like that . – Μελέτης Πέππας Jun 11 '22 at 16:09

1 Answers1

0

The following middleware attempts to find a match on the database. If that is unsuccessful, another attempt is scheduled for a second later. A JSON response is sent only after a successful attempt, but spaces are sent while waiting in the hope that this prevents a browser timeout.

.get("/path", function(req, res) {
  res.type("json");
  async function attempt() {
    var match = await User.find(...);
    if (match)
      res.end(JSON.stringify({match: match.username}));
    else {
      res.write(" ");
      setTimeout(attempt, 1000);
    }
  }
  attempt();
});

If the backend times out requests after, say, 30 seconds, this cannot be used. In this case, consider repeating the requests in the frontend instead:

async function attempt() {
  var match = await axios.get("/path");  // returns 0 or more matches
  if (match.length > 0)
    // Fill results of match into the HTML page
  else
    setTimeout(attempt, 1000);
}
attempt();

But I think this is only a poor substitute for the real solution based on web sockets as suggested by balexandre.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • remember, because it's an HTTP request, if you wait for more than 30 sec, the server will return a TIMEOUT error – balexandre Jun 12 '22 at 14:15
  • Neither my browser nor my server times out after 30 seconds. The browser continues to receive the additional bytes (the spaces) sent by the server. – Heiko Theißen Jun 13 '22 at 10:01
  • 1
    HTTP_TIMEOUt is set on the server, [Heroku](https://www.heroku.com/) for example won't allow you to have a response waiting for more than 30 sec... remember that what happens locally is not the same when you put your code live – balexandre Jun 13 '22 at 11:55