|
本帖最后由 lunux2008 于 2013-11-1 20:40 编辑
1.首先这不是一个常见问题,传统刷页面的方式不会遇到
2.同一时间只有一个AJAX请求的时候也不会遇到
3.同一时间有两个或两个以上AJAX请求必然遇到
配置文件:
$config['sess_expiration'] = 30; //设置session的有效期是30秒
$config['sess_time_to_update'] = 5; //session更新间隔是5秒
遇到的问题是:
每隔2秒钟,同时发起2个AJAX请求控制器的两个不同ACTION,每当到5秒钟 更新SESSION的时候,SESSION就失效了。
---------------------------------------------------------------
function sess_update()
{
if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
{
return;
}
$old_sessid = $this->userdata['session_id'];
$new_sessid = '';
while (strlen($new_sessid) < 32)
{
$new_sessid .= mt_rand(0, mt_getrandmax());
}
$new_sessid .= $this->CI->input->ip_address();
$new_sessid = md5(uniqid($new_sessid, TRUE));
$this->userdata['session_id'] = $new_sessid;
$this->userdata['last_activity'] = $this->now;
$cookie_data = NULL;
if ($this->sess_use_database === TRUE)
{
$cookie_data = array();
foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
{
$cookie_data[$val] = $this->userdata[$val];
}
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
}
$this->_set_cookie($cookie_data);
}
--------------------------------------------------------------
看了一下 session.php 文件的代码,在update() 方法里最后这句,它会用新生成的session_id 替换原来的session_id,在数据库里会替换,同时把新的session_id放到cookie发到客户端,期望的是客户端下次用session_id来请求。但是如果是同时发出了两个AJAX请求,那么第一个到达的AJAX请求会执行到修改库里的SESSION_ID这里,新的SESSION_ID会写到客户端,但是第二个到达的AJAX还是在用老的SESSION_ID来访问,这个时候 用老的SESSION_ID到库里查数据当然结果是空的,然后会给第二个到达的AJAX请求创建一个新的空的SESSION,并又给客户端发出一个了更新的SESSION_ID。这一轮结束之后,SESSION就失效了。
解决的办法是
1.$this->userdata['session_id'] = $new_sessid; 这句注释掉。
2. $this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now, 'session_id' => $new_sessid), array('session_id' => $old_sessid)));
变成
$this->CI->db->query($this->CI->db->update_string($this->sess_table_name, array('last_activity' => $this->now), array('session_id' => $old_sessid)));
就是不让原来的session_id 被修改,永远使用原来的session_id, 只延长 last_activity 上次访问时间
|
|