如何使用会话获取用户的在线时长?

In yii I need to store the users _login time,logout time and total duration logged_ Using session.

I am new to session concept. I don know how to retrieve the total logged time, login time, log out time. In session table it stores only id--expire--data

My code for storing session is

protected/config/main.php

            'components'=>array(

    'session'=>array(
            'class' => 'CDbHttpSession',

            'connectionID' => 'db',
            'sessionTableName' => 'dbsession',
        ),
    ),

All working fine but data stored in db are encrypted. So I am unable to retrieve the data I need. One more thing what data is stored in session table.

Alternative way I used without session but that also have problem. I used this for getting login time, logout time and total duration logged

I used a table activity with fields

id,username,user_activity,url,ip,time 

Codes to fill datas in table when user login and logout is below

protected/controller/sitecontrollers.php

         public function actionLogin()
        {
                /* log in */

                $model=new LoginForm;

                // if it is ajax validation request
                if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
                {
                        echo CActiveForm::validate($model);
                        Yii::app()->end();
                }

                // collect user input data
                if(isset($_POST['LoginForm']))
                {
                        $model->attributes=$_POST['LoginForm'];
                        // validate user input and redirect to the previous page if valid
                        if($model->validate() && $model->login())                                                                               
                               {
                                $activity = new Activity;
                                $activity->username = Yii::app()->user->id;                          
                                //$activity->userId = Yii::app()->user->id;
                                $activity->user_activity = "1";
                $activity->url=$_SERVER['HTTP_REFERER'];
                $activity->ip=$_SERVER['REMOTE_ADDR'];
                                // This breaks the site when log in details are wrong
                                $activity->save();
                                if($activity->save())
                                $this->redirect(Yii::app()->homeUrl);
                    }                          


                }

                // display the login form
      if(Yii::app()->user->id==null)
      {
                  $this->render('login',array('model'=>$model));
      }
         else
           {
         throw new CHttpException(404,'User already logged in.');
             }
        }

        /**
         * Logs out the current user and redirect to homepage.
         */
       public function actionLogout()
        {


                // log
                $activity = new Activity;
                $activity->username = Yii::app()->user->id;
                $activity->user_activity = "0";
        $activity->url=$_SERVER['HTTP_REFERER'];
        $activity->ip=$_SERVER['REMOTE_ADDR'];
                $activity->save();      


                Yii::app()->user->logout();   
                                if($activity->save())                                  

                $this->redirect(Yii::app()->homeUrl);
        }

In this way all workin fine but when browser closed the application is logged out and a data not entering in to the database.then the calculation of duration is getting wrong. So only I took the method session but don't know how to use.

i think you will never do such kind of thing corectly but with some mistake (more or less some minutes, depends on your needs).

1. Keeping alive with page requests

You could send alive status to your ajax page actionImAlive and more often you do that, more precisely you will tell how long user session was. If you do that alive thing 1 time in 5 minutes, you will have duration with ~5min mistake.

  1. Add columns t_login, t_last_activity
  2. on User login update t_login and t_last_activity with current timestamp
  3. On every user new page load check if need to update t_last_activity

    Main Controller *(components/Controller.php)

    public function keepAlive( ) {
            User::model()->updateByPk( 
                Yii::app()->user->id, 
               // array('t_last_activity' => 'NOW()') //CURRENT_TIMESTAMP
             array('t_last_activity' => new CDbExpression('NOW()')) //CURRENT_TIMESTAMP..this working fine 
        );
    }
    
    // Runs after any action in controller
    public function afterAction($action) {
        self::keepAlive();
        parent::afterAction($action);
    }
    
    // This action can be reached by ajax every 5min 
    // if user stays in one page long enaugh
    // (write javascript..)
    public function actionImAlive() {
        self::keepAlive();
    }
    
  4. Above code updates t_last_activity every time user loads new page, but you could do it every 5min by saving last activity timestmap in user session and check it before executing keepAlive() function

    Other controllers

    All other controllers uses Controller class as parent

    SiteController extends Controller
    MyController extends Controller
    SomeController extends Controller
    

2. For user display only (calculates duration from login time to now: now() - t_login)

If you want to display this session duration to user (why you should want to do this I don't know, but anyway..) you could just add t_login column to User table and calculate duration time on a fly.

These was top of my head.