Dynamic room removal by group?

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

Ilithios
Posts: 15
Joined: 04 Apr 2012, 12:12

Dynamic room removal by group?

Postby Ilithios » 12 Jul 2012, 16:32

Hi folks,

So basically here's the deal. I have a bunch of groups with rooms defined in a database. When a user logs in, he is automatically part of a group. I have an extension that checks to see if the rooms defined in the database exist in SmartFox and adds them if they do not, then subscribes the user to the room group so he can see the list of rooms. It works great except that when the first person to log into the group leaves, all the rooms disappear for everyone else. Of course they are recreated if anyone leaves and comes back or anyone else comes in, but that's a silly thing make people deal with. Is there any way to make rooms that get removed whenever there are no users subscribed to the room group to which they belong?

Thanks,
Bryan
User avatar
Lapo
Site Admin
Posts: 23027
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: Dynamic room removal by group?

Postby Lapo » 13 Jul 2012, 07:17

Hi Bryian,
I think it all depends on how you are creating these Rooms, in other words the settings you are using.

It is not normal that all Rooms disappear when a User leaves, unless you have assigned the ownership of those Room to the User itself. In that case all empty Rooms will be removed when the user goes away (default behavior, can be changed).

There are two ways to handle this:

1- Do not make the User the owner of the Room, instead pass a null as the owner parameter, which indicates that the Server itself owns the Room (see server side javadocs for more details)

2- You can assign the Room ownership to anyone but then configure the Room's RemoveMode to NEVER, which indicates that the Room should never be removed.

One more note on option 2: if you plan to create a lot of Rooms indefinitely you will also need to implement a strategy for removing some of the unused Rooms otherwise you might consume all memory if you create hundreds of thousands of them.
Lapo
--
gotoAndPlay()
...addicted to flash games
Ilithios
Posts: 15
Joined: 04 Apr 2012, 12:12

Re: Dynamic room removal by group?

Postby Ilithios » 13 Jul 2012, 09:08

Hi,

Yes, I know I can make rooms not get removed, but I want them to be removed, not only so that they don't hang around in the system creating memory problems but also because properties of the rooms can be changed in the database, and then the version in SmartFox would never get the update, but I don't want the rooms to change when people are still using them or logged into their group even if the definition in the database changes, so I create them every time someone logs in. Here's an idea I have but don't know about the practicality of implementing it:

1. Make rooms not dynamic (as you talked about)
2. Handle an event that is thrown whenever a user is removed from the server (I'll need to handle such an event anyway for other reasons. How do I do this?)
3. In the event handler check to see what room group the user was in
4. Check that room group to see if there are no more users subscribed
5. Check the room group to see of all tables in it are empty
6. Remove all rooms in that group if there are no users subscribed and all rooms are empty
7. Check what room a user came from and what room group that room is in
8. repeat 4, 5, 6

This seems to handle the case when a user quits and was not in a room but was keeping the rooms alive by being subscribed to the room group, and also the case when a user was not subscribed to a room group but was keeping the rooms alive by being in one of the rooms.

Sound feasible?
User avatar
Lapo
Site Admin
Posts: 23027
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: Dynamic room removal by group?

Postby Lapo » 13 Jul 2012, 14:34

Okay.
2. Handle an event that is thrown whenever a user is removed from the server (I'll need to handle such an event anyway for other reasons. How do I do this?)

Register a server event handler for the USER_LOST event.
See the details here:
http://docs2x.smartfoxserver.com/Advanc ... extensions
http://docs2x.smartfoxserver.com/api-do ... oc/server/
Lapo

--

gotoAndPlay()

...addicted to flash games
Ilithios
Posts: 15
Joined: 04 Apr 2012, 12:12

Re: Dynamic room removal by group?

Postby Ilithios » 13 Jul 2012, 15:15

Can you explain the difference between USER_LOST, USER_DISCONNECT, and USER_LOGOUT? I have read the api docs on these and they are sparse and ambiguous to say the least. In fact, I don't even see a USER_LOST event.

Here's what I have now and it seems to work in my very limited testing so far, but I used USER_DISCONNECT. It also seems like there must be a better way than iterating through every user in the system to find if any are subscribed. Surely the server keeps a list of users subscribed to groups somewhere so it can send updates to them appropriately.

Code: Select all

public class DisconnectHandler extends BaseServerEventHandler
{

    @Override
    public void handleServerEvent(ISFSEvent evt) throws SFSException
    {
        Zone zone = (Zone)evt.getParameter(SFSEventParam.ZONE);
        User user = (User)evt.getParameter(SFSEventParam.USER);
        List<Room> rooms = (List<Room>)evt.getParameter(SFSEventParam.JOINED_ROOMS);

        for (Room room: rooms)
        {
            removeRooms(room.getGroupId(), zone);
        }
       
        List<String> groups = user.getSubscribedGroups();
        for (String group: groups)
        {
            removeRooms(group, zone);
        }

        //clean up the user

    }
   
    private void removeRooms(String group, Zone zone)
    {
        for (User user: zone.getUserList())
        {
            if (user.getSubscribedGroups().contains(group)) return;
        }
        if (zone.getUsersInGroup(group).size() == 0)
        {
            List<Room> rooms = zone.getRoomListFromGroup(group);
            for (Room room: rooms)
            {
                getApi().removeRoom(room);
            }
        }
    }
}
Devon
Posts: 41
Joined: 12 Apr 2011, 16:18

Re: Dynamic room removal by group?

Postby Devon » 14 Jul 2012, 04:28

Based on their names, I'd make the assumption that USER_DISCONNECT is an expected disconnect from the server. Likewise, USER_LOGOUT would be an expected logout (while maintaining a connection). USER_LOST however, sounds like an event that fires when the user disappears, such as an unexpected disconnect...

I too am unable to find it in the [ 2X Documentation ] and Eclipse code assist does not give an option for SFSEventType.USER_LOST. Would it be related to [ isFrozen() ] (which also has inadequate documentation)?

According to [ this link ], and ignoring the typo:
The Is forzen ["Is frozen"] parameter, when true, indicates that the client has lost its connection, but the server is waiting before declaring it as disconnected (this is part of the HRC system implemented in SmartFoxServer 2X; check the feature description in the documentation for more informations [information]).


Notice the use of the term "lost", presumably to indicate that it was not expected and that the user simply dropped or disconnected without going through the disconnection procedure.
User avatar
Lapo
Site Admin
Posts: 23027
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: Dynamic room removal by group?

Postby Lapo » 14 Jul 2012, 08:23

I am sorry I must have confused the event name, I erroneously wrote USER_LOST but it is USER_DISCONNECT
In any case all events are documented in the javadoc:
http://docs2x.smartfoxserver.com/api-do ... tType.html

Would it be related to [ isFrozen() ] (which also has inadequate documentation)?

No, no relation. When you don't find documentation is because it is not meant as an API method call. Unfortunately the javadoc is very limited in hiding the unnecessary methods (and the way it was originally thought is simply preposterous)
Lapo

--

gotoAndPlay()

...addicted to flash games
Ilithios
Posts: 15
Joined: 04 Apr 2012, 12:12

Re: Dynamic room removal by group?

Postby Ilithios » 14 Jul 2012, 16:13

So I take it that iterating through all the users is indeed the best way find out if a room group has no subscribers?
Devon
Posts: 41
Joined: 12 Apr 2011, 16:18

Re: Dynamic room removal by group?

Postby Devon » 14 Jul 2012, 16:37

I've not worked with room groups but it would be a long task to loop through each user and see if they're subscribed to a group if you have a lot of users logged in.

It may be more effecient (and how I'd probably end up doing it) to getSubscribedGroups() from the user on USER_DISCONNECT and then create a function shouldRemoveGroup() to loop through each of the rooms in each of the group (note the nested loop within a loop here) and then check to see if room.getUserList().size() > 0. If any of them rooms have 1 or more users, return false to break the loop. Otherwise, return true at the end of the loop cycle and have the calling function remove the group.
Ilithios
Posts: 15
Joined: 04 Apr 2012, 12:12

Re: Dynamic room removal by group?

Postby Ilithios » 14 Jul 2012, 17:17

Devon wrote:It may be more effecient (and how I'd probably end up doing it) to getSubscribedGroups() from the user on USER_DISCONNECT and then create a function shouldRemoveGroup() to loop through each of the rooms in each of the group (note the nested loop within a loop here) and then check to see if room.getUserList().size() > 0. If any of them rooms have 1 or more users, return false to break the loop. Otherwise, return true at the end of the loop cycle and have the calling function remove the group.


Actually this only checks to see if there are any users IN rooms in the groups, and there's actually a much easier way to find that out. As you can see in my code above, Zone.getUsersInGroup(groupName) will return the total number of users in all rooms that belong to the group.

However, it is possible for a user to be subscribed to a group but not actually be in any room. That's where the problem comes in.
Devon
Posts: 41
Joined: 12 Apr 2011, 16:18

Re: Dynamic room removal by group?

Postby Devon » 14 Jul 2012, 17:30

Ahh, ok. I see the problem. In that case, I'd be debating between doing the loop on all users or keeping track of users using my external database.

If you have a lot of users, it may be more efficient to throw their usernames or id's into a database table associated with a group name when they connect/join.. Then, on USER_DISCONNECT, getSubscribedGroups() and query the database to see if such groups have subscribers...

Return to “SFS2X Questions”

Who is online

Users browsing this forum: No registered users and 130 guests