我想在Yii 2应用程序中统计所有在线用户,您的解决方案是什么?
即使我想计算经过身份验证的用户。一种解决方案是在登录时过度使用authenticate方法,登录后我在db中设置记录。但在这里我有一个问题。我该如何确定用户何时离线?如果我在注销操作中更改在线标志它有一些问题。也许有些用户没有登录就关闭浏览器。然后数据库将在线显示他。什么是这个问题的最佳解决方案?
修改
我的问题是如何超越会话过期方法。不改变过期时间。更详细地说,我想确定用户是否处于离线状态,即使他在没有注销操作的情况下关闭浏览器
答案 0 :(得分:3)
您可以在数据库中存储会话,框架将为您处理到期日期。
此示例来自高级模板,我从前端用户处获取会话。
我需要创建并使用自定义组件来存储用户ID。
1)在db:
上创建一个表 CREATE TABLE `session_frontend_user` (
`id` char(80) CHARACTER SET utf8 NOT NULL,
`user_id` int(11) DEFAULT NULL,
`ip` varchar(15) CHARACTER SET utf8 NOT NULL,
`expire` int(11) DEFAULT NULL,
`data` longblob,
PRIMARY KEY (`id`),
KEY `expire` (`expire`)
) ENGINE=InnoDB
2)从该表中创建一个模型:
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "session_frontend_user".
*
* @property string $id
* @property integer $user_id
* @property string $ip
* @property integer $expire
* @property resource $data
*/
class SessionFrontendUser extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'session_frontend_user';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'ip'], 'required'],
[['user_id', 'expire'], 'integer'],
[['data'], 'string'],
[['id'], 'string', 'max' => 80],
[['ip'], 'string', 'max' => 15]
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'user_id' => 'User ID',
'ip' => 'Ip',
'expire' => 'Expire',
'data' => 'Data',
];
}
}
3)更改config / main.php中的配置
'components' => [
'session' => [
'class' => '\frontend\components\CustomDbSession',
// 'db' => 'mydb', // the application component ID of the DB connection. Defaults to 'db'.
'sessionTable' => 'session_frontend_user', // session table name. Defaults to 'session'.
],
4)在path \ frontend \ components中配置中创建自定义组件'CustomDbSession':
<?php
namespace frontend\components;
use Yii;
use yii\db\Connection;
use yii\db\Query;
use yii\base\InvalidConfigException;
use yii\di\Instance;
class CustomDbSession extends \yii\web\DbSession {
public $writeCallback = ['\frontend\components\CustomDbSession', 'writeCustomFields'];
public function writeCustomFields($session) {
try
{
$uid = (\Yii::$app->user->getIdentity(false) == null)?null:\Yii::$app->user->getIdentity(false)->id;
return [ 'user_id' => $uid, 'ip' => $_SERVER['REMOTE_ADDR'] ];
}
catch(Exception $excp)
{
\Yii::info(print_r($excp), 'informazioni');
}
}
}
答案 1 :(得分:2)
没有直接的方法来确定用户是否离线,如果您曾经测试过Facebook(以及其他网站),您会很快意识到这一点。
最常见的方式(如果您查看适用于Facebook的Chrome网络工具,他们直到最近才会这样做,可能仍然如此)是使用某种隐藏的iframe来制作一个&#34;心跳&#34;到服务器上说用户还在那里。
通常最好不要依赖会话(特别是如果您使用多种设备类型)用户是否已登录,而是更多来自经过身份验证的来源的请求。因此,我会立即在线存储&#34;用户上的字段,并在每次心跳时ping该字段。