Page 1 of 1

Structure question

Posted: 12 Jun 2006, 17:30
by Elgueu
Hello ;)

I have an app where users can walk through a map (in a room), and also change map (they change room). My problem is that i would like to create a chat in this app allowing all users to talk together, even if they are in different rooms.

The basic idea i had is to create a "Chat room" and log all the users in this room. So each user is logged in 2 rooms, one "static" and one which changes for every map (like in the multichat example). The problem is that to broadcast the position of users in different rooms i'm using setUserVariables(), like in the avatar chat example. Everything worked fine until i tried to log every user into two rooms at the same time, because now the user variables of every user are updated through the chat room even if the users are not on the same map...

So what is the best solution to build such a structure ?

Posted: 12 Jun 2006, 21:23
by Virusescu
First of all. I don't see why you have that problem. Whenever you get the onRoomVariablesUpdate message you also get the roomObj from where the variables where updated. With proper planning you can still log users in different more than one room.
HOWEVER, sending a public chat will only work for the curently active room. - Lapo.. please revise this as I'm not so sure anymore about it - Couldn't find it in the docs :)
Withouth server side code, you could have a lobby where all users are logged in and when they choose a map they join that room also, but never quit the mainLobby room.
This way you could use the lobby to send messages between all users and still use your curent room / map structure.

With server side you could build a simple zoneLevel extension with a method like sendMessage that recieves parameters like (msg)...
and then send it to all the users in the zone like

Code: Select all

function handleRequest (cmd, params, user, fromRoom)
{
    if (cmd == "sit") {
       // cmd send using str raw format - params[0] is the message
       var response = new Array();
       response.push("publicMessage");
       response.push(user.getName());
       response.push(params[0]);
       _server.sendResponse (response, - 1, null, getAllUsers() , "str");
    }
}
function getAllUsers() {
   var zone = _server.getCurrentZone();
   var allRooms = zone.getRooms();
   var allUsers = new Array();
   for (var r in allRooms) {
       allUsers.concat(allRooms[r].getAllUsers());
   }
   return allUsers;
}
Then, on the client side you check if the extension message is "publicMessage" (resObj[0] == "publicMessage"); and use resObj[2] for userName that sent the message and resObj[3] for the message.

Only problem here is that if users are allowed to connect to multiple rooms there will be duplicated entryes in the array returned by the getAllUsers() method and, I don't know how SFS behaves but I suppose that, SFS will send a duplicated message to that users. Meaning if a user is connected in 4 rooms at the same time, he might just recieve the same message 4 times. But i'm not sure as I haven't tested this.
If this happens just remove the duplicates form the allUsers array bassing your decision algorithm on a property like userId.

Ok.. it's late.. hope you make something out of this message :)

Posted: 13 Jun 2006, 05:41
by Elgueu
I'll come back in a few hours to study in depth your message but before going to work i want to point out that i don't use onRoomVariablesUpdate(), but setUserVariables() to broadcast the position of users in the map. And i can't pass a RoomId argument in setUserVariables() as i could do with onRoomVariablesUpdate()...

Posted: 13 Jun 2006, 06:40
by Virusescu
Oh oh oh.. now I see.
You set the variables on the user, rather than on the room as I first thought.
How is the ideea of using an extension sounds to you?

Posted: 13 Jun 2006, 11:37
by Elgueu
Ok, so your idea is to keep the actual structure of my app (one room per map, and the users are only logged in one room), and simply use an extension which will broadcast a message sent in a room, to all the other rooms (without using the sendPublicMessage() function).

Well, it sounds great for me, i may recode the chat this way. I just want to be sure there is no simplier way to do it ? Lapo, can you confirm please ?

Thank you for your help ;)

Posted: 13 Jun 2006, 12:14
by Lapo
Sorry there's one thing that is not clear. If one client sends a message, this should be broadcasted to all users?

Sounds a little odd, because if your map has 100+ clients the chat will be mess. Too many messages will be sent and received and following a discussion would become nearly impossible (imagine what would happen if you had 1000 users)

It would be better to structure the application like an instant messenger, where you can see the entire database of users, add them to your buddy list, search them etc... then you could create one-on-one chats or small chat rooms for 4, 8, 12 users

Posted: 13 Jun 2006, 16:13
by Elgueu
Yep, you're right ^^
I don't think i will reach so much users at the same time soon, but i will re-think the structure, a common chat only for the users on the same map will be sufficient.

I may use Virusescu's example for broadcasting special messages... Anyway, is this the good way to send multiroom messages ?

Posted: 13 Jun 2006, 16:33
by Lapo
Yes, and I'd reccomend doing it from the server side.
The sendResponse() method accepts a list of users, so all you have to do is populate the list with users of multiple rooms.

Posted: 13 Jun 2006, 16:36
by Elgueu
Ok thanks ;)