论坛首页 Web前端技术论坛

AJAX 反推技术的一点疑问

浏览 16800 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-09-13   最后修改:2011-09-13
看看这个吧,一般是使用comet实现的。
http://en.wikipedia.org/wiki/Comet_%28programming%29
0 请登录后投票
   发表时间:2011-09-13   最后修改:2011-09-13
squll369 写道
axiheyhey 写道
ajax反推技术并非真正意义上的服务器推,只是一个模拟。主要是基于HTTP长连接
相关介绍:http://www.ibm.com/developerworks/cn/web/wa-lo-comet/


长连接看了这个,有点了解了,轮询可否再指点一下?


上面的链接都介绍了啊。。long-polling和streaming,两者都属于长连接。。
1. long-polling就是轮询,客户端发起一个请求,服务器阻塞请求,直到有新的消息或超时后返回一个respone,客户端再收到respone后继续发起一个请求,如此循环。优点是服务器负担较小,缺点是即时性较差。
2. stream一般是通于隐藏iframe,这个iframe向服务器发起一个请求,服务器会一直保持这个请求直接超时或通信出错,期间一旦有数据,客户端就会接收到,有点像是浏览器向服务器请求一个永远也下不完的文件一样。这种方式即时性更高,缺点是我们看到的页面一直会处于加载状态,服务器负担大。
0 请登录后投票
   发表时间:2011-09-14  
这两种方式一直保留着实体网络连接,一旦客户端数量比较多的时候,感觉会对web服务器的服务能力有比较大的影响
0 请登录后投票
   发表时间:2011-09-14  
tsoukw 写道
这两种方式一直保留着实体网络连接,一旦客户端数量比较多的时候,感觉会对web服务器的服务能力有比较大的影响

+1
0 请登录后投票
   发表时间:2011-09-15  
我的博客上用的是long-polling,已经抛弃这个东东了,呵呵。
0 请登录后投票
   发表时间:2011-09-15   最后修改:2011-09-15
axiheyhey 写道
ajax反推技术并非真正意义上的服务器推,只是一个模拟。
1. long-polling就是轮询,客户端发起一个请求,服务器阻塞请求,直到有新的消息或超时后返回一个respone,客户端再收到respone后继续发起一个请求,如此循环。优点是服务器负担较小,缺点是即时性较差。


基于这个,我写了一个demo:

在客户端我写了一个请求,在页面load的时候发起,去我定义的onlineinfo这个servlet去后台请求,readyState 为3的时候,我获取数据,readyState为4的时候,请求结束,我重新发起请求。

function loadOnlineInfo(){
    var req = initXMLHTTPRequest();
    url = 'http://127.0.0.1:8080/demo/' + '/onlineinfo';

    if(req){
        req.onreadystatechange = onReadyStage;
req.open("POST",url,true);
req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
req.send();
    }
}

function onReadyStage(){
    var ready=this.readyState;

    if(ready==1){

    }else if(ready==2){

    }else if(ready==3){
        onlineInfo = this.responseText;
        if(onlineInfo){
            //do front logic
        }
    }else{
        //re-create request
        loadOnlineInfo();
    }
}

在onlineinfo这个servlet里,我阻塞请求,代码如下:

int onlineNums = OnlineUserHolder.getOnlineUsers().size();
User user = (User)req.getSession().getAttribute(ELSConstant.KEY_SESSION_USER);

//Block Server
while(OnlineUserHolder.getOnlineUsers().size() == onlineNums){
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
        logger.debug("[" + user.getLoginName() + "] Still waitting new user login...");
    }
    。。。。。
    out.write(json.toString());
    。。。。。

OnlineUserHolder这个类,我定义了,当前用户的在线信息,OnlineUserHolder.getOnlineUsers().size()可以获得当前用户的在线数,如果有变化,就推出循环阻塞,返回数据给前台。


这样的Demo出来以后,我使用了一下,发现是可以达到我要的效果,当别人登陆的时候,自己的页面会立刻显示出该用户上线了,而不用刷新页面。

但是还有几个问题:
1 在页面load的时候发起请求,也就是说,这个页面一刷新,就发一个请求到后台,被后台阻塞着,也就是说,后台服务的一个线程就阻塞在那里,如果刷新了好多次页面,那不就开了好多个线程,而且,用户有可能转到其他的页面,这个线程的返回对他来说也没有意义了,那有什么好的解决方案吗?

比如,对一个sessionid + userid只开一个请求?

2.好像是线程安全的问题,这个demo对于 相互登陆有bug. 比如A用户登陆,在这个页面上观察,然后B用户登陆了,在A用户的页面上,B用户登陆的状况会立刻显示出来,然后B用户注销,B用户注销的状况也会立刻显示出来。 但是反之,如果A用户登陆,然后B用户登陆了,A用户注销,在B用户的页面上,就不会显出出A用户注销的状况。我还用研究一下,这个问题,有人能大概估计一下是什么问题吗?
0 请登录后投票
   发表时间:2011-09-15  
squll369 写道

但是还有几个问题:
1 在页面load的时候发起请求,也就是说,这个页面一刷新,就发一个请求到后台,被后台阻塞着,也就是说,后台服务的一个线程就阻塞在那里,如果刷新了好多次页面,那不就开了好多个线程,而且,用户有可能转到其他的页面,这个线程的返回对他来说也没有意义了,那有什么好的解决方案吗?

比如,对一个sessionid + userid只开一个请求?

2.好像是线程安全的问题,这个demo对于 相互登陆有bug. 比如A用户登陆,在这个页面上观察,然后B用户登陆了,在A用户的页面上,B用户登陆的状况会立刻显示出来,然后B用户注销,B用户注销的状况也会立刻显示出来。 但是反之,如果A用户登陆,然后B用户登陆了,A用户注销,在B用户的页面上,就不会显出出A用户注销的状况。我还用研究一下,这个问题,有人能大概估计一下是什么问题吗?


今天头有点沉,懒得看你的code了。。关于你的第一个问题是现实存在的,所以才会有bayeux之类的协议产生来解决这类问题。关于第二个问题,因为我没看你的code,所以我只能说可能是。。应该是。。你的实现有点瑕疵。
0 请登录后投票
   发表时间:2011-09-15  
OK,
我加了一个List<String> sessionIdwithUserId = new ArrayList<String>();这2个问题都解决了!

在loop阻塞前,

User user=(User)req.getSession().getAttribute(ELSConstant.KEY_SESSION_USER);
String sessionwithUserid = req.getSession().getId() + "-" + user.getUserId();

if(checkSessionIdWithUserId(sessionIdwithUserId, sessionwithUserid)){
    return;
}else{
    sessionIdwithUserId.add(sessionwithUserid);
}

然后阻塞一结束,remove掉
//remove sessionidWithuserid
sessionIdwithUserId.remove(sessionwithUserid);

本来是想解决第一个问题的,试验下来,第2个问题也解决了。。。还要再分析分析。赫赫,谢谢了!

做了一个练习,终于算对这个反推,小有理解了。
0 请登录后投票
   发表时间:2011-09-19  
我一直奇怪!
0 请登录后投票
   发表时间:2011-10-13  
我们用的是nodejs+socket.io
缺点是稳定性稍差,学习成本比较高,还有和现有系统的对接。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics