Join rooms sharing auth

Hi everyone,
Is there any example on how to use multiple rooms? And also how to share the authentication between different rooms?
In my current flow I'm logging the user using a first game-room, sending credentials and using the onAuth method in the Room server.
But then I would like to use different rooms for different maps, so which will be the best way to accomplish this?
I know I can use room = client.join('game_room', userData); on the client side but what should I do to leave the room and move the user from one room to the other?
Also, will be possible to validate if the user was already authenticated before leave the first room? I really don't want to run all the validation process through the DB again.
Maybe I could leave one room available as "logged-users" and allow users to join other rooms by checking if they are "active" in that specific room, I did some tests on that but didn't find a way to access other rooms on server side.

Thanks again!

@dpastorini said in Join rooms sharing auth:

don't want to run all the validation process through the DB again.

Well, I use a traditional way for that. I produce a token for each client when they first login to the server. Then, they use the token and their ID whenever they join to a new room. Following that, the server checks if ID&token pair exists in the DB.

I think the method above is quite cheap. Another easy thing would be to have a global object in the server that is independent of any room, which keeps the credentials of the users. You can use such global objects to check if a user is already authenticated.

Hi @halilbilgin , thanks for your reply!

Well, I use a traditional way for that. I produce a token for each client when they first login to the server. Then, they use the token and their ID whenever they join to a new room. Following that, the server checks if ID&token pair exists in the DB.

That will be the same as use the user/password from the user object on the server side (which I don't share on the client) and hit again the DB. Even when that's is just a cheap query it will be still a query and a Promise to wait for information.

Another easy thing would be to have a global object in the server that is independent of any room, which keeps stores the credentials of the users. You can use such global objects to check if a user is already authenticated.

This is more like what I'm looking for, that's why I was thinking to use something like a "logged-users" room, as something global. That's why I was asking if Colyseus has something like this already implemented or if I will need to extend the Colyseus server class to make a custom implementation on my own (if this is the case it will be something that I would share later), but the way I see it, it could be something as part of Colyseus "core".

Also I didn't find any good join/leave rooms flow sample, so maybe I'm missing something?

Thanks!

Yes, I got what you mean and I am also interested in some built-in way for this kind of needs.

For join/leave room procedure, I do it by sending message from client to server or vice versa first, then close the connection in both sides, which is not nice :/.

For join/leave room procedure, I do it by sending message from client to server or vice versa first, then close the connection in both sides, which is not nice :/.

Yeah, exactly, I saw the client.leave and room.join on the client side, and the Room.close on server side, but I wasn't able to get for example a rooms list on server side from inside a room. Do you know if there's a way to do that? Or do you have any ideas on how to do it?

Best,

Ok, I think I was able figure it part of how to do this by reading other posts...
For reference: https://discuss.colyseus.io/topic/149/using-multiple-rooms-to-support-one-large-map/10
There says to use room.presence functions for multiple rooms, so now I'm able to check if the user really left the first room before allow it to join the second with something like if(this.presence.keys[roomId+':'+client.id]), will this be ok?
There's none documentation about any of this, all I saw about presence there was related to the server and Redis, which I don't think it's the same, right?
Best,

Hi @dpastorini, sorry the delay to answer. I've just published some docs for Presence here: http://colyseus.io/docs/api-presence/

Just be careful when using Presence methods manually to avoid memory leaks. It's common to set values there and forget to clean them up.

That's great!!! Thank you @endel ! :D
I'm still struggling on how to change rooms and keep using the same logged user data, and in between I broke my Phaser implementation, so I'll probably rollback my last changes and start again just by using the presence methods.
I'll keep you posted on how it goes and let you know as soon I get a working sample.
Thanks again!

Hi @endel , one more question: let's say I'm on the Room1, and then I join Room2, is possible in the server side to access the data that's already in the Room1?
Because in the examples you have something like room.state.players[client.sessionId], so I would like to know if it's possible to access the data in first room from the second, maybe using super.allRooms[roomId] or something like that?

Thanks!

Hey @dpastorini, that's not possible. You can do it by storing the data you'd like to retrieve in the presence (e.g. this.presence.hset("roomxyz", "key", "value")), and then retrieving it in the other room (this.presence.hget("roomxyz", "key")).

I wouldn't recommend doing this, though. It's likely that you'll face some issue when the data is not available anymore, in case the room gets disposed, for example.

Hi @endel thanks for you quick reply, as you said... yeah.. too many issues already LOL
I'll go for the database option to persist the data between room changes, I'm working on it now, the idea is to save the player progress > leave the room > join the new room > re-authenticate the user with the data in the session and reload the progress.
I though it will be too expensive in terms of server response time, but keep a room or persist too much information in the presence could end up been even more expensive than just hit the DB to get the data.
Best,