The answer to your question is "it depends". You can implement this in several ways. The best solution depends upon the nature of the games in the "rooms" and how many simultaneous players will be in connected. For example, a single Godot server app can probably handle a few hundred poker players, but maybe only a dozen or less PVP real-time battle players.
First, you need to become very familiar with Godot's built-in RPC networking support. Godot's RPC support is great, but it was built-in primarily for P2P games where one player acts as the server. This means that the "server" and the "clients" are all running exactly the same code. HOWEVER, the built-in networking works very well for dedicated server apps also.
The key knowledge point is that RPC calls between "peers" (which includes the server) relies completely on the node_path and function name on both ends of the connection. There is no requirement for the code in the server and clients to be the same. Only the node-paths need to be the same.
The best way I've found to do this is to place all RPC "remote" functions in one or more auto loaded singletons. So the paths for these nodes is simply "/root/singleton-name".
For example, an auto-loaded node named "rpcfunctions" will have a node-path of "/root/rpcfunctions". Let's say you have a function that is called for user login. In the client's version of rpc_functions this might be
signal user_validation(results);
# called from client login scene to check user name and password
func user_login(username:String, password:String)->void:
rpc(1, "authenticate_user", {"username":username, "password":password});
# called remotely from server to return authentication results
remote user_login_callback(results:Dictionary)->void:
# Use a signal to send the results to whatever logic needs it
emit_signal("user_validation", results);
In the server version of rpc_functions you will need a method like this.
remote func authenticate_user(params:Dictionary)->void:
var results:Dictionary = {};
# Do user validation and populate results
# send authentication results back to the calling client
rpc(get_tree().get_rpc_sender_id(), results);
If your game will be truly massive-multiplayer, you'll likely need a much more scalable server-side solution. For example, look at Nakama server which is very scalable but does not support Godot's built-in RPC networking and is challenging to set up don't have a lot of experience with server administration.
Hope this helps.