最近做一个小的基于Flex的网页聊天室,其实并没有用到多少Flex的技术,只是最近在学习这个东西,才做这个小的聊天室。聊天室的基本功能都已经实现时测试这个小的软件,忽然发现聊天室的在线人数计算很不准确,经过层层排查,发现问题出现为了防止浏览器崩溃等原因而得不到用户下线的轮训机制上。这个功能没有用Flex实现,而是用js写了一个小的Ajax脚本,定期向服务器发送一个请求,服务器也在监听这个请求,如果长时间没有请求送达服务器,则判定其因为某些原因掉线,将其从在线列表中移去。
功能很容易实现,脚本也很快就写好,当时只是在Firefox和chrome中测试了一下发现没问题(因为我平时用Chrome上网,Firefox开发,所以当时就用了这两个浏览器测试了下崩溃问题),今天再次用IE测试了下,发现了在线人数的计数不准确,最后排查发现问题就出在上述的机制里,在IE中轮训只执行了一次就不在执行。
代码:
- setInterval("interRequest();", 3000);
- function interRequest(){
- if(xmlhttp_request == null){
- createXmlRequest();
- }
- var id = getURL();
- var req = /:/g;
- id = id.replace(req, "@");
- var url = "/ChatRoom/CheckUserOnService?id="+id+"&sid="+uuid;
- xmlhttp_request.open("GET", url, true);
- xmlhttp_request.send(null);
- xmlhttp_request.onreadystatechange = xmlstatechange;
- }
网上资料很少,开始还以为setInterval方法在不同浏览器中执行的问题,后来发现IE对setInterval的支持出了参数传递,其余全部可以,那就很奇怪了,为什么在其他浏览器里都没问题,在IE里就只执行一次就不再执行了呢?
查了半天资料,忽然一条不起眼的消息让我猛然惊醒,在IE里,对于同一个URL地址,IE短期内是不会再去访问服务器,而是读取缓存内的内容。问题终于大白,虽然设置了轮询,但是URL一直都是同一个,IE默认的不再访问服务器了。这样事情就好办了,给URL再加个时间戳之类的参数,果然可以可以正常轮询了(FLYXIONG注:如url改为url+"?ran="+new Date().getTime();,ran参数命名随意,另外,加时间戳不要用random(),因为随机数再大也有可能重复;当然就执行效率来说,random()会快很多)。
问题其实不难,主要是好久没有使用Ajax之类的技术,把应注意的点都忘记了。在此把这个问题记录,以防以后再次出现这种问题找不到资料。。