本帖最后由 dr21c 于 2015-09-14 15:59:09 编辑 先说环境:
windows 2003 iis+php+mysql
阿里云 4核4G 5M 的云服务器;
当前问题:(已多次测试,可以排除操作因素)
a,竞拍出价过快,页面卡住(只有五个人的情况下)
b,$GLOBALS['user_info']数据丢失,一刷新页面,用户已不在登录状态,程序管理后台也退出了。
本想做到300人同时在线竞拍,现在5个人都搞不定,
自已研究出来的,业务逻辑代码写得很差,求版主和各位大神指点一下,
程序实现方式:
一,会员登录,验证成功以后,生成的是$GLOBALS['user_info'],验证会员是否在线状态,使用的是这个变量而不是session
二,竞拍实现方式,
1, 先查询 数据库报名记录,未报名不允许参加竞拍:$had_sign = $GLOBALS['db']->getOne("select id from ".DB_PREFIX."sign where deal_id= " . $dat['id'] . " and user_id = " . $udata['id']);
2, 再查询 这个竞拍项目的当前价(竞拍出价表),如果(竞拍出价表)当前价不存在,则去取值(竞拍项目表)的起拍价,通过这一步得出,竞拍项目的当前价。
3,判断用户出价,是否比当前价高,否则不予通过。
4,以上条件满足,插入(竞拍出价表)最新价格数据。
5,ajax_return($data); ajax返回最新数据。
【中间我做了一些限制】
// 用写入库的方式,限制提交频率
$c_time = $GLOBALS['db']->getOne("select create_time from ".DB_PREFIX."estate_biding_lock where deal_id= " . $dat['deal_id'] . " and user_id = " . $dat['user_id'] . " order by id desc limit 1");
if($c_time){
if( (time() - $c_time) ..... 以写进数据库的方式,时间间隔 限制提交频率。
// 用生成文件的方式,限制提交频率
$lockfile = "lock.txt";
if(file_exists($lockfile)){
$data['state'] = 0;
$data['info'] = "
竞拍激烈,请稍侯出价...";
ajax_return($data);
exit;
}else{
// 生成锁定文件
$myfile = fopen($lockfile, "w");
$txt = "lock";
fwrite($myfile, $txt);
fclose($myfile);
}
竞拍出价成功后,后面做了删除。
竞拍页面:
A,竞拍开始后,setTimeout("get_auction_list()", 1000); 每秒钟都在 $.post 查询数据库,获得最新的出价列表和最新价,显示在页面上,即ajax实时更新,
// 得到最新的出价列表
1,查询数据库的此项目的最新出价数据,并对数据进行了处理和判断。
2,再次查询数据库最新的一条出价记录,获得最新的价格。
3,查询这个项目的起拍价和每次加价幅度(固定),返回新的最低出价。(这一步刚刚想到解决掉不查询了)
4,ajax返回数据。
------解决思路----------------------1. 代码存在sql注入
2. 用户信息存储global不靠谱,为何不用session
3. 用文件的方式实现锁,太奇葩了,如果程序出问题了,锁可能永远都解不开了
------解决思路----------------------$GLOBALS 只在当前页中有效,不能作为 验证会员是否在线状态
用户已在登录状态时,不需要再查报名表,而是在登录时就先设置好转态
直接 replace 竞拍价,当然要加上报价>竞拍价 的条件
select 出 竞拍价 返回给用户
ajax 长轮询实时性不好,应考虑 websock