Php 拉威尔在线状态

Php 拉威尔在线状态,php,laravel,Php,Laravel,我制作了自定义中间件来跟踪用户的在线状态,但它有一个问题,我可以看到自己的在线状态,但我总是看到其他用户处于离线状态,而他们不是 代码 中间件 class UserActivity { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed

我制作了自定义中间件来跟踪用户的在线状态,但它有一个问题,我可以看到自己的在线状态,但我总是看到其他用户处于离线状态,而他们不是

代码
中间件

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(模型)

视图

@if($user->isOnline())
  Online
@else
  Offline
@endif
知道为什么其他用户的状态总是不正确吗?


PS:
如果有livewire解决方案,我愿意:)

也许您应该使用数据库?我这样做:

在授权中间件中:
app(WriteUserRepository::class)->updateLastractive()

在存储库中:

 public function updateLastActive()
{
    $this->model = ReadUserRepository::getCurrentUser();
    $this->model->last_active = now();

    return $this->save();
}
用户模型中的UsersOnline范围如下所示:

 private const timeToOffline = 120; // seconds

public static function boot()
{
    parent::boot();
    static::addGlobalScope(function ($query) {
        $query->where('last_active', ">", Carbon::now()->subSecond(self::timeToOffline));
    });
}
然后你可以得到所有的在线用户,并用它做你想做的事情。如果您的用户模型很大,则只能从用户存储库创建特定查询,并只选择在线用户ID,而不选择所有信息。

Jquery:

setInterval(()=>{
 $.post('yourUrl.php',{user_id:user_id},(send_online)=>{ console.log(check_online );} );
},200000); //2minutes interval
Php:

检查部分(服务器端php):


在聊天中挖掘之后,我们解决了问题

缓存驱动程序问题 您必须使用
CACHE\u DRIVER=file

原因
数组
仅用于测试目的,请求之间的缓存中不会保留该状态

Livewire关键问题 当内容位于
foreach
if
条件内并由livewire更新时,您必须使用


Livewire保留它们的引用以更新DOM。如果没有,Livewire可能会更新错误的位置。

缓存
存储在用户的web浏览器中,因此您只能获取在线数据,在您的情况下,请使用
websocket
状态channel@KamleshPaul这是有道理的,除了使用websocket之外,我们还有什么办法可以将其公开,而不是存储在用户浏览器中?因为它在共享主机上运行并且运行js依赖项不是websocket的可选使用
pusher
,所以您不需要配置websocket服务器并创建一个状态频道,所以当用户访问您的网站时,它将加入该频道,如果离开该频道,那么您就可以实现缓存存储在用户浏览器中是正确的。。它存储在服务器中,默认情况下使用服务器的文件系统。使用ajax运行代码,在数据库中每2分钟更新一次当前时间以及用户id,您只需检查更新的时间和当前时间之间的差异是否在120秒内。如果是,则用户处于联机状态,否则用户处于脱机状态。我已经在很多项目中使用了这个简单的技巧,除了延迟和低效率之外没有问题@马福尔蒂斯
setInterval(()=>{
 $.post('yourUrl.php',{user_id:user_id},(send_online)=>{ console.log(check_online );} );
},200000); //2minutes interval
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 ]);
}
$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"; } 
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);
}