Reputation: 7138
I have made custom middleware to track user online status but it has an issue, I can see my own online status but I always see other users as offline while they are not.
Middleware
class UserActivity
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::check()){
$expiresAt = Carbon::now()->addMinute(1);
Cache::put('user-is-online-' . Auth::user()->id, true, $expiresAt);
}
return $next($request);
}
}
Kernel.php
'web' => [
//...
\App\Http\Middleware\UserActivity::class,
],
User.php (model)
public function isOnline()
{
return Cache::has('user-is-online-' . $this->id);
}
views
@if($user->isOnline())
Online
@else
Offline
@endif
Any idea why other users status is always not correct?
PS:
I'm open to livewire solution if any :)
Upvotes: 0
Views: 2039
Reputation: 6108
After digging in the chat we have resolved the issues;
Instead of using CACHE_DRIVER=array
you have to use CACHE_DRIVER=file
Reason : array
is used for testing purpose only and the state will not be persisted in cache between requests.
You have use <livewire:my-component key="UNIQUE_ID" />
or <div wire:key="UNIQUE_ID"></div>
when the content is inside a foreach
or if
condition and updated by livewire.
Livewire keeps reference of them to update the DOM. Without, Livewire may update the wrong place.
Upvotes: 1
Reputation: 412
Jquery :
setInterval(()=>{
$.post('yourUrl.php',{user_id:user_id},(send_online)=>{ console.log(check_online );} );
},200000); //2minutes interval
Php :
if(isset($_POST['user_id'])){
$user_id = $_POST['user_id']; $current_time = date('d-m-Y g:i:s');
$query = $con->prepare("Update users set last_online = ? where user_id = ?");
$query->execute([$current_time,$user_id ]);
}
Checking part (server side php):
$getUser = $con->prepare("Select * from users where user_id = ?");
$getUser->exec....and fetch etc then check
if(timeDiff($Users->last_online) < 2){ echo "is_online";} else{ echo "offline"; }
Time diff checker function :
function timeDiff($last_online){
$to_time = strtotime(date('d-m-Y g:i:s'));
$from_time = strtotime($last_online);
return round(abs($to_time - $from_time) / 60,2);
}
Upvotes: 0
Reputation: 46
Maybe you should to use database? I do so:
In authizied middleware:
app(WriteUserRepository::class)->updateLastActive();
In repository:
public function updateLastActive()
{
$this->model = ReadUserRepository::getCurrentUser();
$this->model->last_active = now();
return $this->save();
}
UsersOnline scope from User model looks like:
private const timeToOffline = 120; // seconds
public static function boot()
{
parent::boot();
static::addGlobalScope(function ($query) {
$query->where('last_active', ">", Carbon::now()->subSecond(self::timeToOffline));
});
}
Then you can get all online users and do what you want with it. If your User model is big you can create only specific query from users repository and select only online users Ids without all information.
Upvotes: 0