I know this is an old question, but here is what I've developed using WordPress token sessions.
First of all, I've developed a function that update timestamp of current session. If I access to a web page where I'm connected, login timestamp and expiration timestamp are updated (login to current timestamp)
add_action('init', function() {
$sessions = get_user_meta(get_current_user_id(), 'session_tokens', true);
$session = $sessions[hash('sha256', wp_get_session_token())];
$duration = $session['expiration'] - $session['login'];
$sessions[hash('sha256', wp_get_session_token())]['login'] = current_time('U');
$sessions[hash('sha256', wp_get_session_token())]['expiration'] = current_time('U') + $duration;
update_user_meta(get_current_user_id(), 'session_tokens', $sessions);
});
After this, I calculate time passed after user login in actives sessions.
If this time between current and login is less than 5 minutes, I think user is "online". If this time is between 5 and 20 minutes, I think user is "away".
function is_user_online($user = null) {
if (is_null($user)) {
$user = get_current_user_id();
}
$session_time = false;
$sessions = get_user_meta($user, 'session_tokens', true);
foreach ($sessions as $session) {
$time = current_time('U') - $session['login'];
if ($time == false || $time < $session_time) {
$session_time = $time;
}
}
if (is_numeric($session_time) && $session_time <= 1200 && $session_time > 300) {
$session_time = 'away';
} else if (is_numeric($session_time) && $session_time <= 300) {
$session_time = 'online';
} else {
$session_time = false;
}
return $session_time;
}
I've also modified session life. 1 hour for normal and 7 days for "remember me".
add_filter('auth_cookie_expiration', function($seconds, $user_id, $remember){
if ($remember) {
$expiration = 7*24*60*60;
} else {
$expiration = 60*60;
}
if (PHP_INT_MAX - time() < $expiration) {
$expiration = PHP_INT_MAX - time() - 5;
}
return $expiration;
}, 99, 3);
With this solution you can't know if user is online at real time but I think is a great solution :)