我目前正在Laravel(5.3)上制作应用程序,并要求列出所有登录用户。我原本打算将它们存储在MySQL中,但被告知Redis会更适合这项工作。一旦我查看Redis文档,我将把所有用户存储在一个集合中,但后来意识到您无法为单个成员设置过期时间,因此选择了命名空间字符串。如何列出Laravel和Redis中的所有登录用户?
我写了一些代码,我相信它运行正常,但想要改善它/解决任何可能出现的问题的建议。
因此,首先,这里有两个功能我LoginController.php
// Overriding the authenticated method from Illuminate\Foundation\Auth\AuthenticatesUsers
protected function authenticated(Request $request, $user)
{
$id = $user->id;
// Getting the expiration from the session config file. Converting to seconds
$expire = config('session.lifetime') * 60;
// Setting redis using id as namespace and value
Redis::SET('users:'.$id,$id);
Redis::EXPIRE('users:'.$id,$expire);
}
//Overriding the logout method from Illuminate\Foundation\Auth\AuthenticatesUsers
public function logout(Request $request)
{
// Deleting user from redis database when they log out
$id = Auth::user()->id;
Redis::DEL('users:'.$id);
$this->guard()->logout();
$request->session()->flush();
$request->session()->regenerate();
return redirect('/');
}
接下来加入我写的中间件,以刷新Redis的到期当用户做一些事情,刷新称为“RefreshRedis”他们会话。
public function handle($request, Closure $next)
{
//refreshing the expiration of users key
if(Auth::check()){
$id = Auth::user()->id;
$expire = config('session.lifetime') * 60;
Redis::EXPIRE('users:'.$id,$expire);
}
return $next($request);
}
我再注册在$ middlewareGroups中间件只是StartSession中间件
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\RefreshRedis::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
后,为了让所有我以前在this线程发现功能的修改版本的用户列表。
class Team extends AbstractWidget
{
/**
* Treat this method as a controller action.
* Return view() or other content to display.
*/
public function run()
{
//Find all logged users id's from redis
$users = $this->loggedUsers('users:*');
return view('widgets.team',compact('users'));
}
protected function loggedUsers($pattern, $cursor=null, $allResults=array())
{
// Zero means full iteration
if ($cursor==="0"){
$users = array();
foreach($allResults as $result){
$users[] = User::where('id',Redis::Get($result))->first();
}
return $users;
}
// No $cursor means init
if ($cursor===null){
$cursor = "0";
}
// The call
$result = Redis::scan($cursor, 'match', $pattern);
// Append results to array
$allResults = array_merge($allResults, $result[1]);
// Get rid of duplicated values
$allResults = array_unique($allResults);
// Recursive call until cursor is 0
return $this->loggedUsers($pattern, $result[0], $allResults);
}
}
当用户的会话过期时,他们的登录会自动过期。所以你没有理由实现这个逻辑。 你可以在'config/session.php'中配置这个''lifetime'=> 120'默认值是2小时 – WebKenth
等等,我将如何得到所有当前登录用户的列表而没有这个逻辑? – Dalek
并不是说你不能制作活跃用户的列表,只是说你不需要写实验逻辑。您只需在登录时添加用户,并在会话过期时将其删除,然后您可以随时查询列表以获取活动用户。 – WebKenth