今天,个人任务是,在 Laravel 应用程序用户我的资料页面上,用户名旁边添加一个绿点,表示他们是否在线。我首先想到的是,咱们将须要启动一个 node.js 服务器并跟踪每一个用户的活动套接字链接。而后用当前登陆的用户套接字,咱们能够实时更新在线状态!惟一的问题是,这是咱们目前的要求,有点超过顶部,并无彻底必要的,直到咱们的功能,须要达到第二个准确性,如实时聊天。php
一位同事指出,对于目前的需求,MySpace 用来处理 “在线” 功能的方式可能就足够了。就咱们所知,MySpace 用来显示用户是否在线的方式是基于他们在网站上的最后一项活动。若是他们的最后一次活动在 X 分钟内,咱们会显示 “在线” 徽章,若是没有,咱们不会。简单!node
让咱们为用户的上次活动在用户表中添加一个字段,而且在请求每一个页面时更新它。而后当咱们须要检查用户是否在线,咱们能够将该时间戳与当前时间戳进行比较,若是在 X 分钟内,则他们在线!虽然这能够工做得很好,这取决于你正在构建的应用程序,它会向数据库添加没必要要的 写入,这会在某种程度上下降你应用程序的速度。一个好的折衷办法是将这些信息存储在应用程序缓存中。 缓存的好处是能够简化这种方法,由于能够设置缓存为过时。web
如今咱们决定使用缓存实现这个特性,下一个问题是这个代码应该在哪里运行,以便它在每一个请求上运行?我有两个想法能够实现:数据库
建立一个 BaseController,让你全部的 Controller 都继承它
建立一个中间件
通过一些思考,并意识到我须要在全部已经编写的构造函数中添加对父构造函数的调用,我选择在中间件中实现。api
咱们有个计划,让咱们进入代码!数组
首先,咱们须要建立一个中间件。在终端中输入如下命令:缓存
php artisan make:middleware LogLastUserActivity
接下来咱们打开如下 php 文件服务器
app/Http/Middleware/LogLastUserActivity.php.
在其中的 handle 方法中添加下面的代码:app
1 if(Auth::check()) { 2 $expiresAt = Carbon::now()->addMinutes(5); 3 Cache::put('user-is-online-' . Auth::user()->id, true, $expiresAt); 4 }
接下来,咱们打开 app/Http/Kernel.php 文件。若是您使用的是 Laravel 5.1 或 更早的版本, 您应该把代码直接放置到 $middleware 数组中。 若是您的版本是 5.2.* , 您应该把代码放置到 $middlewareGroups 的 web 中 。注意,必定要把代码放到 StartSession 中间件的下方,不然 Auth 门面将不会正确在 user 中记录 log。个人更新配置设置以下:函数
1 protected $middlewareGroups = [ 2 'web' => [ 3 \App\Http\Middleware\EncryptCookies::class, 4 \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 5 \Illuminate\Session\Middleware\StartSession::class, 6 \Illuminate\View\Middleware\ShareErrorsFromSession::class 7 \App\Http\Middleware\VerifyCsrfToken::class, 8 \App\Http\Middleware\LogLastUserActivity::class, 9 ], 10 'api' => [ 11 'throttle:60,1', 12 ], 13 ];
最后一步是添加一个方法到咱们的 user 对象中去检测这个值。在 app/User.php 咱们添加下面的方法:
public function isOnline() { return Cache::has('user-is-online-' . $this->id); }
如今在任何页面中你就能添加下面的方法:
1 @if($user->isOnline()) 2 user is online!! 3 @endif
重要提示 -- 确保在你的文件顶部使用 use 引入全部的 facades!
我但愿上面这些能帮助到大家解决这个问题!