Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+2 votes
1.8k views
in Q2A Core by
closed by
I noticed that the function qa_get_logged_in_userid() does not work properly.

Especially, if user logged in ticking "Remember Me".

I have a plugin that check the function qa_get_logged_in_userid() in every 3 minutes adds record to a database table sending data of userid and currentime. If users is not logged in after 3 minutes the row in database will be deleted.

I noticed that userid=1 which admin is always logged in.

I tried close browser. Nothing change. The only thing is log out action.

Plus, my another demo users that I remember logged in ticking  "Remember Me" also appears logged in.
Q2A version: q2a 1.7.5 customized
closed with the note: I have solved the problem with ajax polling check.
by
That's how it should behave rt? Remember me means until session ends user must be logged in.
by
I know, therefore, I am saying that qa_get_logged_in_userid() function actually does not show currently visiting users.
by
yes, thats true. It cannot be used for getting currently active users - I suppose there is no Q2A function which does that.

2 Answers

+1 vote
by
Due to the stateless nature of the HTTP protocol, it makes no sense to find what users are actually executing a request in a given point in time. That would only get all users which are in the middle of a connect and disconnect stage. Depending on the HTTP version, other objects, in addition to the main request, could also be fetched using the same connection, such as images. This doesn't make any difference, though, so we can consider this as a page load.

Once a disconnection is executed, which would happen immediately after a page load, the link between the user and the server is gone. In order to workaround this, wrappers around this stateless approach have been created, for example, cookies and server-side sessions. They will give the impression that users are logged in between requests and avoid authentications between requests.

However, each request will have access to their own session. Getting information from other active sessions is a security risk. Usually PHP and web servers work together to manage sessions, usually configured as files stored in a given directory. Those files are usually cleaned by a Cron job (in *nix-based systems). Once the file is removed, the session is lost.

Rather than getting deeper into this it might be better to make some clarifications. The logout works pretty well to understand when a session is killed. The problem is that unless a user logs out, and as long as the cookie is set and the session is active (the operating system has not removed it yet), the user will be able to access the site without the need to actually log in. So monitoring logouts and logins make sense as session observers.

However, if you consider an "active user" as user that has logged in your site in the last 3 minutes, you will be expecting people to input user and password every 3 minutes in order to observe their logins, and that's not going to happen.

In short, if you want to keep track of active users just follow a keep-alive approach. Each time a user refreshes a page, just insert/update the record in the database with the current time. Then remove the ones with a Cron job, if you want that approach.

Extra tip 1: you can improve performance significantly avoiding updating the database in every request by playing with cookies or session information.

Extra tip 2: most likely you'll want to create a composite key on the update time column and then on the user id, in that order (although this might depend on the exact SQL queries you're running).
by
actually I am doing the same. I am sending  'userid' derived by qa_get_logged_in_userid() and current time through ajax to a php page where php code does updating/adding or deleting operations for database table. It checks on each qa_request(). If there is no any qa_request() then each 3 minutes.
If there is no any updates in time at database, the that users row is deleted.
However, as I use  qa_get_logged_in_userid() function, the users who logged in ticking remember me, appears always logged in.
by
> I am sending  'userid' derived by qa_get_logged_in_userid() and current time through ajax to a php page

I might not be getting that properly. If you are talking about AJAX that means you're making client-server interaction. If you send the id and the time to a PHP page (server) then you must have the id and the time in the client-side, which seems to be unnecessary. You don't need AJAX. Furthermore, you could even use 'NOW()' in the SQL insert/update to avoid having to worry about timezones for the keep-alive.

All you need to do is to figure out what requests you want to catch. For example, if you want to catch EVERY request, you could use a 'process' module.

> However, as I use  qa_get_logged_in_userid() function, the users who logged in ticking remember me, appears always logged in.

That is also a bit confusing to me.
 1. Where do they appear as "logged in"?
 2. Also why are you talking about "they", if the qa_get_logged_in_userid() function returns only the current logged in user performing the request?

I'm also assuming you're also making use of a custom table, because you mentioned "deleting operations". In the approach you mentioned if a user does not perform a web request in more than 3 minutes then the timestamp will be more than 3 minutes old and will be deleted by the CRON job. Take a look at this plugin: https://github.com/arjunsuresh/Q2A-OnlineUsers I haven't tested it but a bird's eye view of the code will show you a similar approach.
by
reshown by
Yes,  actually I use NOW() in mysql. I just wanted to explain that I am updating current time.
by
Suppose a widget page where I get current users id with $userid = qa_get_logged_in_userid();

On the same page I run a custom function that writes $userid and current time onto database table.

I have js file where I use ajax post in order to check polling and catch user state.

If test is on 4 different users where A and B is logged in by ticking remember me, and C and D without ticking it.

The problem is A and B is always appears online. However, the code works pretty good for users  C and D. If they make any request they appear online, when they stay actionless for a certain time they turn to idle state. And after further certain time they are removed from the database table. It works good for C and D. But not A and B.

As @arjunsuresh commented above, I guess this function should not be used to catch online users.
by
You keep referring to "users" when you talk about the qa_get_logged_in_userid() function. It WILL NOT return the "users" that are logged in, but rather the user ID of the user whose session is currently executing in the web server. Furthermore, as Arjun mentioned, "It cannot be used for getting currently active USERS". The plural seems to be the main misunderstanding and cause of the bug.

If you want to get the active sessions in the web server, then re-read the answer :)

Anyway, active sessions in the web server makes absolutely no sense. Just use the currently logged in user to self update their own record in the database in every page load, so you don't need Q2A to give you all active users as you keep track of them one by one. I think that is as far as I can get with the information I have
by
the plural 's' is typo. I think you actually understand that I mean userid.  You say "Just use the currently logged in user to self update their own record in the database in every page load". that's what I did in my custom plugin.

I am just addressing another issue. I am saying that this method work for all users except who logged in by ticking remember me checkbox. Self-update of records keeps occurring even if the user does not visit the site.
It happens only for users who once before l logged in with remember me checkbox.
0 votes
by
I have solved the problem with ajax polling check.
...