java异步长轮询_Servlet 3.0笔记之异步请求Comet推送长轮询(long polling)篇补遗

上篇文章有些东西言犹未尽,这里补遗,使之理解更为全面些。

还多亏了jQuery,提供了JSONP请求的方法:

$.getJSON('http://192.168.0.99/servlet3/getjsonpnew?callback=?')指定需要回调的参数名callback,但其值使用一问号替代,作为占位符,jQuery会自动贴心的生成一个随机的调用函数名,服务器端的生成结果:

jQuery150832738454006945_1297761629067('2011-02-15 17:20:33 921');我们直接在success函数中直接获取传入的值,无须担心那个看起来怪怪的回调函数名。JSONP的原理,在页面头部区动态产生一个JS文件引用(有人称为动态标签引用)。

虽然这一切看起来很好,很贴心,但也存在着不少问题:

无法直接显示指定回调函数名完美主义者可能无法忍受长长的、怪怪的函数名;当然了,可以定制的东西,总是让人很舒心

在长连接情况下,浏览器会一直显示正在加载中图示jQuery生成的JSONP JS文件在长连接情况下,会一直加载中,可能会影响到良好的用户体验,也会让前端UI体验师比较闹心。

很显然jQuery无法满足我们更高的实际要求。怎么办,请出jQuery-JSONP组件,基本上可以满足我们的要求。服务器端代码没有什么变化,有所变化的是客户端代码。

Comet JSONP TEST

String.prototype.template=function(){

var args=arguments;

return this.replace(/\{(\d )\}/g, function(m, i){

return args[i];

});

}

var html = '

'

'

{0}
'

'

last date : {1}
'

'

'

';

function showContent(json) {

$("#showDiv").prepend(html.template(json.content, json.date));

}

var jsonpUrl = "http://192.168.0.99/servlet3/getjsonpnew";

function initJsonp(){

$.jsonp({

url: jsonpUrl,

callbackParameter: 'callback',

callback : 'yongboy', //eg:http://192.168.0.99/servlet3/getjsonpnew?callback=yongboy&_1297934909500=

success: function(json) {

if(json.state == 1){

showContent(json);

}

initJsonp();

},error: function(data) {

}

});

}

$(function (){

// 为了兼容opera浏览器,设置为20秒延时时间(我本地测试若大于20s,可能出现连接中断问题)

if($.browser.opera){

jsonpUrl = "?timeout=20000";

}

initJsonp();

});

loading ...

嗯,jQuery-JSONP组件提供了更为灵活的jsonp参数配置:指定回调函数名

提供错误处理函数,兼容opera

在目前大部分浏览器中没有加载进度显示

经测试:

IE

页面不刷新,效果很满意。jQuery-JSONP源代码:

if ( browser.msie ) {

script.event = STR_ONCLICK;

script.htmlFor = script.id;

script[ STR_ONREADYSTATECHANGE ] = function() {

/loaded|complete/.test( script.readyState ) && callback();

};

// All others: standard handlers

}使用了IE浏览器onreadystatechange加载事件等特性。

Firefoxscript[ STR_ONERROR ] = script[ STR_ONLOAD ] = callback;

browser.opera ?

// Opera: onerror is not called, use synchronized script execution

( ( scriptAfter = $( STR_SCRIPT_TAG )[ 0 ] ).text = "jQuery('#" + script.id + "')[0]." + STR_ONERROR + "()" )

// Firefox: set script as async to avoid blocking scripts (3.6+ only)

: script[ STR_ASYNC ] = STR_ASYNC;看来我当前浏览器中3.6版本的火狐支持脚本文件async属性,非阻塞加载,再添加上onload,onerror事件支持,页面不刷新显示,也不难办到了。

Chrome

很不错,当前作为主力的Chrome浏览器也支持脚本文件的async属性,效果同3.6版本火狐。

Opera

情况很糟糕,在Windows Opera 11.01以及Ubuntu Opera 11.00下测试,长轮询时间若长于20秒,则会出现连接中断情况。样例中在Opear浏览器下设置长轮询过期时间为20s。

浏览器会一直显示为正在加载中的状态。

Opera浏览器中脚本加载不支持onerror事件,只能使用阻塞式的脚本加载机制用以处理有可能发生的异常。

有关阻塞方式实现JSONP,延伸阅读:

Comet (long polling) for all browsers using ScriptCommunicator

Safari

既然同为一个内核的谷歌浏览器也支持脚本文件的async属性,同样的异步加载也是水到渠成的了。

有关浏览器脚本异步加载机制,可进阶阅读:非阻塞式JavaScript脚本介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值