Laravel 中使用简单的方法跟踪用户是否在线
99

今天,我的任务是,在Laravel应用程序用户个人资料页面上,用户名旁边添加一个绿点,表示他们是否在线。我首先想到的是,我们将需要启动一个node.js服务器并跟踪每个用户的活动套接字连接。然后用当前登录的用户套接字,我们可以实时更新在线状态!唯一的问题是,这是我们目前的要求,有点超过顶部,并没有完全必要的,直到我们的功能,需要达到第二个准确性,如实时聊天。

一位同事指出,对于目前的需求,MySpace用来处理“在线”功能的方式可能就足够了。就我们所知,MySpace用来显示用户是否在线的方式是基于他们在网站上的最后一项活动。如果他们的最后一次活动在X分钟内,我们会显示“在线”徽章,如果没有,我们不会。简单!

让我们为用户的上次活动在用户表中添加一个字段,并且在请求每个页面时更新它。然后当我们需要检查用户是否在线,我们可以将该时间戳与当前时间戳进行比较,如果在X分钟内,则他们在线!虽然这可以工作得很好,这取决于你正在构建的应用程序,它会向数据库添加不必要的 写入,这会在某种程度上降低你应用程序的速度。一个好的折衷办法是将这些信息存储在应用程序缓存中。 缓存的好处是可以简化这种方法,因为可以设置缓存为过期。

现在我们决定使用缓存实现这个特性,下一个问题是这个代码应该在哪里运行,以便它在每个请求上运行?我有两个想法可以实现:

  1. 创建一个 BaseController,让你所有的 Controller 都继承它
  2. 创建一个中间件

经过一些思考,并意识到我需要在所有已经编写的构造函数中添加对父构造函数的调用,我选择在中间件中实现。

我们有个计划,让我们进入代码!

首先,我们需要创建一个中间件。在终端中输入以下命令:

php artisan make:middleware LogLastUserActivity

接下来我们打开以下php文件
app/Http/Middleware/LogLastUserActivity.php.
在其中的 handle 方法中添加下面的代码:


if(Auth::check()) {
    $expiresAt = Carbon::now()->addMinutes(5);
    Cache::put('user-is-online-' . Auth::user()->id, true, $expiresAt);
}

接下来,我们打开 app/Http/Kernel.php 文件。如果您使用的是 Laravel 5.1 或 更早的版本, 您应该把代码直接放置到$middleware 数组中。 如果您的版本是 5.2.* , 您应该把代码放置到 $middlewareGroups 的 web 中 。注意,一定要把代码放到 StartSession 中间件的下方,否则 Auth 门面将不会正确在user中记录log。我的更新配置设置如下:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class
        \App\Http\Middleware\VerifyCsrfToken::class,
        \App\Http\Middleware\LogLastUserActivity::class,
    ],
    'api' => [
        'throttle:60,1',
    ],
];

最后一步是添加一个方法到我们的 user 对象中去检测这个值. 在 app/User.php 我们添加下面的方法:

public function isOnline()
{
    return Cache::has('user-is-online-' . $this->id);
}

现在在任何页面中你就能添加下面的方法:


@if($user->isOnline())
    user is online!!
@endif

重要提示 -- 确保在你的文件顶部使用 use 引入所有的 facades!

我希望上面这些能帮助到你们解决这个问题!


Practice makes perfect.

原文地址:https://erikbelusic.com/tracking-if-a-us...

译文地址:https://laravel-china.org/topics/7454/la...

本帖已被设为精华帖!
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 15
GhostCoder

很水地翻译了一小段哈哈

9个月前
hedeqiang

这个翻译功能很攒啊,

9个月前

成功参与一段,小开心

9个月前
MushishiXian

这个翻译板块很棒

9个月前
尼古丁

赞赞赞

9个月前

看起来很棒棒

9个月前
licheng

这个在 Summer 的 larabbs教程 里面差不多就有了 用当前系统时间戳减去最后活跃时间

9个月前
等车的猪

点赞

9个月前
leung0826

能把英文原文链接贴出来就更好了:smile:

9个月前

@leung0826 原文地址请见此处

file

9个月前

请问有没有删除翻译的功能呢,不小心提交了两次一样的内容,没找到哪里可以删除掉重复的提交。。

8个月前
Destiny

这个小技巧炒鸡使用呢!

7个月前

那请问如果想要一次性获取所有在线人数呐?比如说当前活跃人数XX人

7个月前

@未满酱油瓶 这个问题,再用redis设置一个自增的increase key就行了 设置用户在线的时候,让key自增+1 离线-1 建议可以搞个事件监听? 拙见,有更好的可以指出

7个月前

@Rekkles 使用dd(Redis::hGetAll($hash));返回的是数组,直接count就可以了
参考链接

6个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!