2017-02-27 128 views
0

我目前正在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); 
} 
} 
+0

当用户的会话过期时,他们的登录会自动过期。所以你没有理由实现这个逻辑。 你可以在'config/session.php'中配置这个''lifetime'=> 120'默认值是2小时 – WebKenth

+0

等等,我将如何得到所有当前登录用户的列表而没有这个逻辑? – Dalek

+0

并不是说你不能制作活跃用户的列表,只是说你不需要写实验逻辑。您只需在登录时添加用户,并在会话过期时将其删除,然后您可以随时查询列表以获取活动用户。 – WebKenth

回答

1

可以通过使用[多]命令,将最终确定用[EXEC]命令某些Redis的命令(S)到期Redis的组密钥。

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; 

    // In using the [multi] and [exec] command 
    $oLibRedis = $this->callRedisLibrary(); // Initialize your Predis\Client class on this method 
    $oLibRedis->multi(); 
    $oLibRedis->set('users:'.$id, $id); 
    $oLibRedis->expire('users:'.$id, $expire); 
    $oLibRedis->get('users:'.$id); 
    $aResults = $oLibRedis->exec(); 
    return $aResults 
} 

它将从中产生ff。结果

array(3){[0] => object(Predis \ Response \ Status)#224(1){[“payload”:“Predis \ Response \ Status”:private] => string( 2)“OK”} [1] => int(1)[2] => string(5)“admin”}

结果将根据您调用的命令显示为数组远在Redis上(例如设置,过期和获取命令)

当您想要检查会话是否过期或来自其他控制器时。您可以在Redis中使用[ttl]命令。

$sRedisUserKey = $oLibRedis->ttl($sSampleUserKey); // int(7184) 

尝试刷新页面以检查倒计时。希望这对你有所帮助

相关问题