Ejemplo n.º 1
0
 /**
  * 执行一次session gc操作
  * 
  * 算法:
  * 1、在线列表:将ZSet数据集中最后活跃(<time()-$life)所有垃圾销毁掉
  * 2、保持登录:session到期后用户还没出来活动(>deadline)
  * 
  * 1和2可能相交,保持登录用户超时后清除在线列表;销毁前调用session delete()函数
  * 
  * 原ylstu库操作条件:
  * (deadline>0 and deadline<timeNow) or (deadline=0 and ltime=timeNow-keepOline)
  *
  * @param string $sessionId session缓存键
  */
 public function gc($maxlifetime)
 {
     $gcTime = time();
     /**
      * 获取超过在线时间允许的列表并清理之 limit => array($offset, $count)
      * 
      * 取出来数据格式 array($sessionID=>score):
      * Array([yunk5y093qzlcoij5nhbz49ospyay4rp8yilbxli] => 1379425023)
      */
     $endStamp = $gcTime - $this->sessionBase->getLife();
     $kickOnline = $this->redis->zRangeByScore(self::MANAGER_DATALIST, 0, $endStamp, array('withscores' => TRUE, 'limit' => array(0, self::MAX_GC_PER_ACTION)));
     //print_r($kickOnline);die();
     if (!empty($kickOnline)) {
         //这里不能使用redis multi,因为读session可能使用redis
         foreach ($kickOnline as $sessionId => $lastVisit) {
             //删除在线列表中数据
             $this->redis->zDelete(self::MANAGER_DATALIST, $sessionId);
             //删除实体session数据 保持登录的除外
             if (!intval($this->getDeadline($sessionId))) {
                 $this->sessionBase->delete($sessionId);
             }
         }
     }
     /**
      * 处理保持登录过期列表 
      * 
      * 超过一个月无活动的删除session
      */
     $kickAutoLogin = $this->redis->zRangeByScore(self::MANAGER_DEADLINE, 0, $gcTime, array('withscores' => TRUE, 'limit' => array(0, self::MAX_GC_PER_ACTION)));
     //print_r($kickAutoLogin);die();
     if (!empty($kickAutoLogin)) {
         $redisMulti = $this->redis->multi();
         foreach ($kickOnline as $sessionId => $lastVisit) {
             //铁定不在线列表中  从保持登录列表删除
             $redisMulti->zDelete(self::MANAGER_DEADLINE, $sessionId);
             //删除实体session数据,直接删除,从在线列表剔除时更新资料过
             $this->sessionBase->delete($sessionId);
         }
         $redisMulti->exec();
     }
 }