View Full Version : getting a list of users currently online
getApi().getUsers() would give me users in that plugin only? is there a way to get a list of all users online on the server side?
Thanks!
tcarr
12-28-2011, 11:38 PM
That gives you only the users in the room that plugin is attached to. There is no direct way to get a list of all users currently online, but there are several workarounds for this.
1. When a user logs on, have the client automatically join one special room that has all listeners turned off, and never leave that room. He can join other rooms too, so that he is in the room for a game or for chat, but have him never leave that first room. If there is a plugin attached to that first room, it can use getApi().getUsers().
2. If every user is in a room of some kind, a plugin can use getApi() methods to get all the zones and then get all the rooms in each zone, then for each room get the users in that room. This is NOT efficient and will definitely not scale well.
3. Your LoginEventHandler can maintain a concurrent data structure in memory that holds all the users that are online (probably adding in the userDidLogin method). LogoutEventHandler can remove them, or just periodically iterate through the data structure and check which users are online, removing any that are not online.
Is there a reason for getting the list of users currently online? If you just want to send each of them a plugin message or a private message, there's a much simpler way to do it.
i have a list of users to which i want to send a message but only to those users to who are online currently.
and since I let users login multiple times using the same user account, I want to make sure that if such a user is online, I send a message to everyone who's using that user's id. does that make sense?
tcarr
12-28-2011, 11:55 PM
The following getApi() methods will probably do the trick for you.
sendGlobalPluginMessage - send the same plugin message to every user currently online. If one user is logged in with multiple clients using LocalConnection, each of the clients should get the plugin message (if they are listening for plugin messages), but I haven't tested that.
sendGlobalPrivateMessage - send the same private message to every user currently online. Again, if you are using LocalConnection to share a connection, all swfs will get this message.
sendPluginMessageToServer - sends the same plugin message to every user who is in a room. Users in multiple rooms may get multiple copies, and users not in rooms won't get it. You probably don't want to use this one.
The ES5 server can't send messages to users who are not logged in.
but the only thing is that not every online user is supposed to get the message. It's a subset of the current online users that I want to send the message to.
tcarr
12-29-2011, 12:26 AM
Ah ok. The easiest thing is just to iterate through that list and check whether each one is online.
if (getApi().isUserLoggedIn(username)) { ... send a plugin message to username ... }
Whether this is a better solution than maintaining a data structure using your login event handler depends on the number of usernames in the list, and how often a message needs to be sent to these users who are online.
Or you could have your login event handler's userDidLogin method add only the users who are on your list to a special room when they log in, and have the plugin attached to that room send the message when it is needed (and prevent users not on the list from joining that room).
yeah .. that's exactly what I am doing ..
if (getApi().isUserLoggedIn(userid)) {
getApi().sendPluginMessageToUser(userid, response);
// This is what I want to do here : find other users who could be online using the same account as userid
}
tcarr
12-29-2011, 02:12 AM
Perhaps I'm tired, but I really don't understand all these comments about multiple users logged in using the same userId. An ES5 username is UNIQUE - only one person can log on at a give time using that username. The only exception to this is if you are using an AS3 LocalConnectionMirror to share a connection - but that's multiple swfs with the same human using them, because the LocalConnection is on the human's local computer. So I don't see how you could find other users online with the same account as userId.
okay.. so I have modified the login handler such that if I login from two different browsers, es5 lets me login.. lets say I first login from IE and my userid is abc .. then i open Firefox and login using the same userid/password but now internally es5 modifies my userid to abc:<somenumber> which i determine using some parameters so that my number is unique every time. I hope this clears the confusion about multiple users with the same userid logged on to es5. Thoughinternal to es5 they're all different user id's.
now after sending the plugin message to userid abc, I want to find if any of abc:<somenumber> are currently online.
tcarr
12-29-2011, 02:02 PM
There are lots of ways to create groups of users. A Room is the most common group of users, and likely the easiest one for this use case.
When a user logs on, either the client or a plugin should join him to a room that is for his "base userId". In your use case above, the roomName would be "abc" without the number. Have all of these rooms in a separate named zone so that you don't get them mixed up with some other rooms.
If you want all the various "abc" clients to hear events when other "abc" users log on or log off, just have them listen for users joining and leaving that particular room. If you don't want them to hear these events then turn the events off when that room is created.
A plugin would be able to get the list of users in the room for "abc" users by using getApi().getRoomsInZoneByName, then iterate through to find the roomId for the room with room name "abc". It could send a plugin message to all users in that room without even getting the list of those users, but it does need the roomId.
If this needs to be done frequently, then have a ConcurrentHashMap<String, Integer> on the server for the roomName that gives the roomId, so that you don't have to iterate. I'm going to add a ticket to our system to add another getApi() method that will let a plugin look up a roomId from the zoneName and roomName or zoneId and roomName, because that sounds like it would be useful in a number of cases.
kablammyman
01-03-2012, 07:53 PM
im having a similar problem of finding all the users online. I give a list of names, and i send back all the users who are online from that list. I do this before joining a room, so i can give the user the option of joining a room that has one of his friends in it.
however since I'm using es 5.2.3 i have to march thru all the zones, rooms, then users to find out. obviously this is very SLOW. Is there a faster way that i dont know about?
Also, is getApi().isUserLoggedIn(username) in es 5.2.3?
tcarr
01-03-2012, 08:07 PM
getApi().isUserLoggedIn(username) is even available for ES4. We've had that for a LONG time.
UserTracking and RoomTracking was added with ES5.3, so that won't be available if you are still no 5.2.3.
getApi() methods that you may find useful that are available with 5.2.3 or earlier:
getBuddiesOnline: returns the specified user's buddy list, filtered to show only those buddies that are currently online
quickJoinGameWithBuddyForUser: QuickJoinGameRequest only will join to a game that has a buddy playing if there is such a game
findOneGameWithBuddies: returns a GameRO of one game that has a buddy in it, or null if none found
findAllGamesWithBuddies: returns information about all online buddies and the games they are playing
While there is no easy way to look up which rooms a buddy is in that are not games, you could have the clients listen for plugin messages, and have your plugin send a message to each buddy asking what rooms they are in right now. Or you could have a server level plugin maintain a data structure with this info and in the onJoinRoom function in the client you have it send a plugin request giving the zoneId and roomId of the room just joined, and in onLeaveRoom function similarly.
It may be simpler to just make all your rooms into games. Depends on your application.
kablammyman
01-03-2012, 08:11 PM
so, if i was check who is online, i could not see what zone and room those users are in unless they are in different games?
I think each environment is a different game, so i may be able to use the various join game requests.
I really need to talk to my people about upgrading...
tcarr
01-03-2012, 08:22 PM
If your users are in rooms that are not GameManager game rooms, then there's no direct way to find which room a given user is in. You can however do the "send a plugin message to the buddy and the client auto responds with the room it is in" method.
If your users are in rooms that are GameManager game rooms (or can be made INTO GameManager game rooms easily) then findAllGamesWithBuddies should give you enough info.
tcarr
01-03-2012, 08:25 PM
Please note that findAllGamesWithBuddies might not be any faster than your current method. Upgrading to ES5.3.1 is going to give you the fast getApi().getUserJoinedGames and getApi().getUserJoinedRooms.
Powered by vBulletin® Version 4.1.6 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.