更新资料
当我继续对此表示赞同时,我认为有理由记住这个答案已有4年历史了。Web的增长速度非常快,因此请注意这个答案。
我最近也遇到过同样的问题,并对这个问题进行了研究。
给定的解决方案称为长轮询,要正确使用该解决方案,必须确保AJAX请求具有“较大”超时,并始终在当前结束后发出此请求(超时,错误或成功)。
长轮询-客户
在这里,为了使代码简短,我将使用jQuery:
function pollTask() {
$.ajax({
url: '/api/Polling',
async: true, // by default, it's async, but...
dataType: 'json', // or the dataType you are working with
timeout: 10000, // IMPORTANT! this is a 10 seconds timeout
cache: false
}).done(function (eventList) {
// Handle your data here
var data;
for (var eventName in eventList) {
data = eventList[eventName];
dispatcher.handle(eventName, data); // handle the `eventName` with `data`
}
}).always(pollTask);
}
重要的是要记住这一点(来自jQuery docs):
在jQuery 1.4.x及更低版本中,如果请求超时,则XMLHttpRequest对象将处于无效状态;否则,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)。
希望我能帮上忙。