更新
由于我在此回答上不断收到点赞,我认为有必要提醒大家这篇回答已经四年历史。网络发展速度非常快,请注意这一点。
最近我遇到了同样的问题并进行了研究。
所给出的解决方案被称为长轮询(long polling),为了正确使用它,您必须确保您的AJAX请求具有“较长”的超时时间,并且在当前请求结束(超时、错误或成功)后始终执行此请求。
长轮询 - 客户端
这里,为了简洁起见,我将使用jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true,
dataType: 'json',
timeout: 10000,
cache: false
}).done(function (eventList) {
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data);
}
}).always(pollTask);
}
记住,重要的是(来自jQuery文档):
在jQuery1.4.x及以下版本中,如果请求超时,则XMLHttpRequest对象将处于无效状态;访问任何对象成员可能会引发异常。仅在Firefox 3.0+中,脚本和JSONP请求无法通过超时取消;即使在超时期到达后,脚本也将运行。
长轮询-服务器
它不是任何特定语言,但应该是这样的:
function handleRequest () {
while (!anythingHappened() || hasTimedOut()) { sleep(2); }
return events();
}
在这里,hasTimedOut
将确保您的代码不会永远等待,anythingHappened
将检查是否发生了任何事件。 sleep
是为了在没有事件发生时释放线程以执行其他任务。 events
将以JSON格式(或您喜欢使用的其他格式)返回事件字典(或任何其他数据结构)。
它确实解决了问题,但是,如果您像我一样关心可伸缩性和性能,您可能会考虑我发现的另一种解决方案。
解决方案
使用套接字!
在客户端上,为避免任何兼容性问题,请使用socket.io。它尝试直接使用套接字,并在套接字不可用时回退到其他解决方案。
在服务器端上,使用NodeJS创建服务器(示例在此处)。客户端将订阅使用服务器创建的此频道(观察者)。每当必须发送通知时,它都会在此频道中发布,并通知订阅者(客户端)。
如果您不喜欢此解决方案,请尝试APE(Ajax Push Engine)。
希望我有所帮助。