由于浏览器之间的差别,我们不能判断每个用户是否下线,所以我们需要写一个任务,定时将不活跃的用户通过存储过程清除.
Mysql 从5.1.*之后添加了事件调度功能,之前版本似乎是通过win系统的定时任务来调度的.
1. 查看Event_scheduler是否开启
SELECT variable_value FROM information_schema.global_variables WHERE variable_name = 'event_scheduler';
2. 调度任务支持动态开关,布尔值ON/1表示打开,OFF/0表示关闭。
set @@global.event_scheduler=ON;
set @@global.event_scheduler=1;
附: Event
DELIMITER $$ ALTER DEFINER=`root`@`%` EVENT `e_checkclentisonline` -- 每隔5妙执行一次 ON SCHEDULE EVERY 5 SECOND STARTS '2012-06-19 16:37:50' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN -- 调用存储过程 CALL checkclientisonline(); END$$ DELIMITER ;
附:存储过程
DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE `checkclientisonline`() BEGIN -- 这个用于处理游标到达最后一行的情况 declare stop int default 0; declare count_ int default 0; -- 声明在线用户的uid declare uid int; declare ulastdate datetime; -- 找出所有在线的用户 -- 声明游标 declare cur cursor for select clientid from myclient; -- 声明游标的异常处理,设置一个终止标记 declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop=1; -- 打开游标 open cur; -- 读取一行数据到变量 fetch cur into uid; -- 这个就是判断是否游标已经到达了最后 while stop <> 1 do -- 找出当前用户的最后一次讲话时间 select count(*) into count_ from msg where senduid=uid; if count_ = 0 then -- 如果最后一次讲话时间为空,判断其登录时间 select logintime into ulastdate from userinfo where user_id = uid; else select wdate into ulastdate from msg where senduid=uid order by wdate desc limit 0,1; end if; if time_to_sec(TIMEDIFF (now() ,ulastdate)) > time_to_sec('00:00:15') then delete from myclient where clientid=uid; end if; -- 读取下一行的数据 fetch cur into uid; end while; -- 循环结束 close cur; -- 关闭游标 END$$ DELIMITER ;