Can server-side matchmaking be done in the server's verifyClient?

Hello everyone. I stumbled upon Colyseus two weeks ago and so far I am excited about it. It might exactly be what I need and now I am evaluating it for my projects. Currently I have a question about server-side matchmaking.

I've seen endel's example for ranked matchmaking at It does use a special room for matchmaking to which players have to connect to initially. When they are finally matched to a game room, players will be disconnected from the matchmaking room and connect to the game room.

In my project I even want server-side matchmaking, but I would prefer to avoid a such a special room for matchmaking. Ideally the authentication and the matchmaking is done before completely establishing a websocket connection and ideally there is only one websocket connection ever made.

All this being said, here is my question: There is a callback function named "verifyClient" ( which can be used to decide whether the http connection is rejected or upgraded to a websocket connection. Can I cram all my authentication and my matchmaking and my asychronous code (async, await, promises, etc) into that function? Or is that a bad idea? If it is a bad idea, why?

Hi @TeeTeeHaa! 👋 Can you explain your use case describing the real user interaction with the game? It may be easier for me to understand what you need starting with the problem first rather than the solution.

Can I cram all my authentication and my matchmaking and my asychronous code (async, await, promises, etc) into that function?

The verifyClient callback can only deny connections directly before they reach the Room's implementation, the scopes you have there are very limited, and you won't be able to exchange any messages during that, so "matchmaking" can't be done there

Glad to have you here, I hope you stick around! :)

I am thinking of the following situation:

  • The server is JS/TS/node-based.
  • The server has several connected clients already, distributed over several rooms.
  • The client is JS/TS/browser-based.
  • The client reads credentials from browser cookie ("session key") or asks user for credentials.
  • The client opens http connection to server (which will later become a ws connection), sending the credentials as attributes in the http header.
  • In the server verifyClient is called.
  • In there the server then gets the credentials from the http header and verifies them against a database. This should be done asynchronous.
  • If successful the server decides whether there already is an existing room for the new client or whether it should create a new room for the client (the client shall have no say in choosing the room). Creating a room seems to be asynchronous according to the documentation.
  • If successful the server allows the upgrade of the http connection to a ws connection and establishes this connection straight to the room chosen or created right before.
  • The client finally connects to this room.

I hope to stick around, too, because that would mean I will continue using Colyseus :)

Hi @TeeTeeHaa, I see, well there are many ways to go about this, If you'd like to use a traditional cookie/session, you can use this as a starting point: (this example does not use the very latest version of Colyseus, but the sources should look exactly the same using it)

If you'd like to manually control creating and/or using an existing room by yourself, I'd suggest creating an HTTP route for that (e.g. GET /reserve-seat/), and returning a seat reservation (using any of the matchMaker methods that return a "seat reservation" from the server-side), and then consume the seat reservation from the client-side (.consumeSeatReservation()).

Generally using .joinOrCreate("xxx", {...}) is enough, but if you have a very specific use-case you might be better off making your own logic as described above.

I hope this helps! Cheers!

Hello @endel . I will have a look at that example. Your recommendation regarding an HTTP route for authentication and seat reservation sounds like a better idea than the one I explained above. Thank you for your input. 👍