- User A joins Room 1 and User B joins Room 1
- Look at room count as found in room->UserCount(), it shows correctly as 2 users
- User A disconnects from SFS2X (logout and/or disconnect is the same) while still in Room 1
- User B now goes to look at room->UserCount() and sees the value as 0 users even though he has not logged out or left the room
- If checking the backend, User B is still in Room 1 and if trying to join Room 1 again, User B gets an error that he is already in the room
If User A doesn't disconnect but just changes rooms, or if User A leaves the room first before disconnecting, then User B's user count is correct as 1.
So the issue is - why would User B's user count get updated to 0 if he's still in the room when User A disconnects? We traced through the SFS2X C++ API source code and we pinpointed the problem to here. See commented part in the code snippet below that comments out the room->Dispose() loop at the end. By commenting that out, it seems to fix the scenario described above.
But the question then is - why was this code put in in the first place? What should we be aware of the side effects of this modification? It doesn't seem to make sense that User B's room objects get disposed for all rooms that User A was joined in when User A disconnects. Please advise if this is an appropriate fix, any possible side effects, or if there is a correct way to fix/patch this.
Note we are using the 1.1.6 C++ API.
Code: Select all
void SystemController::FnUserLost(unsigned long long context, boost::shared_ptr<IMessage> msg)
{
// Map context
SystemController* instance = (SystemController*)context;
boost::shared_ptr<ISFSObject> sfso = msg->Content();
boost::shared_ptr<string> keyGetInt (new string("u"));
long int uId = *(sfso->GetInt(keyGetInt));
boost::shared_ptr<User> user = instance->sfs->UserManager()->GetUserById(uId);
if (user != NULL) {
// keep a copy of the rooms joined by this user
boost::shared_ptr<vector<boost::shared_ptr<Room> > > joinedRooms = instance->sfs->RoomManager()->GetUserRooms(user);
// remove from all rooms
instance->sfs->RoomManager()->RemoveUser(user);
// remove from global user manager
instance->sfs->UserManager()->RemoveUser(user);
// Fire one event in each room
vector<boost::shared_ptr<Room> >::iterator iteratorJoinedRooms;
for (iteratorJoinedRooms = joinedRooms->begin(); iteratorJoinedRooms != joinedRooms->end(); iteratorJoinedRooms++)
{
boost::shared_ptr<Room> room = (*iteratorJoinedRooms);
boost::shared_ptr<map<string, boost::shared_ptr<void> > > evtParams (new map<string, boost::shared_ptr<void> >());
evtParams->insert(pair<string, boost::shared_ptr<void> >("user", user));
evtParams->insert(pair<string, boost::shared_ptr<void> >("room", room));
boost::shared_ptr<SFSEvent> evt (new SFSEvent(SFSEvent::USER_EXIT_ROOM, evtParams));
instance->sfs->DispatchEvent(evt);
}
[color=#FF0000]/* for (iteratorJoinedRooms = joinedRooms->begin(); iteratorJoinedRooms != joinedRooms->end(); iteratorJoinedRooms++)
{
boost::shared_ptr<Room> room = (*iteratorJoinedRooms);
room->Dispose();
room = boost::shared_ptr<Room>();
}
joinedRooms->clear(); */[/color]
}
}