2013-08-27 21 views
1

我试图使用ajax调用我的服务器上的流式端点。连接应该能够永久接受来自服务器的推送数据,但XMLHttpRequest似乎缓冲整个响应。我只想让浏览器客户端接收每个数据块一次并转到下一个数据块。如何防止XMLHttpRequest缓冲整个响应

有什么办法可以防止这种行为?

更新:似乎Firefox有能力通过设置XMLHttpRequest.responseType等于“moz-chunked-text”或“moz-chunked-arraybuffer”来支持此功能。不过在其他浏览器中不支持。无论如何,这可能不是最好的方法。

WebKit equivalent to Firefox's "moz-chunked-arraybuffer" xhr responseType

+0

Ajax并非真正意义上的永久开放和多个消息传递。它可以完成,但你自己决定响应的哪一部分是* new *或者你需要定期回收连接([长时间轮询](https://en.wikipedia.org/wiki/Push_technology# Long_polling))。适合该角色的是[WebSockets](https://developer.mozilla.org/en-US/docs/WebSockets)。 –

+0

流HTTP端点(没有websocket切换)因此不适合基于浏览器的客户端使用? – cachance7

+0

换句话说,如果服务器数据以高频率进行流式传输,那么长时间轮询将会丢失数据。 – cachance7

回答

1

看看这个维基http://en.wikipedia.org/wiki/Push_technology

我相信你在想什么的是长轮询。如果服务器将其输出为分块(请参阅How to make PHP generate Chunked response for php示例)

一旦您有服务器发送分块响应,您可以使用类似https://github.com/flowersinthesand/portal这样的内容来连续读取数据流。

如果你不能改变你的服务器传输编码,或者你必须坚持使用ajax,另一种方法是让你的客户端向服务器轮询更改。像(使用jQuery缩短这个)

setInterval(function(){ 
    // last_updated lets you compare what's changed since the last call so you can stream updates. Or you could have the server respond with a certain amount of bytes, and then have this param remember where they are in the stream and send the next X bytes 
    $.get("/my/endpoint?last_updated=" + (new Date().getTime()), function(d){ 
     console.log("Got response"); 
    }); 
}, 5000); // Refresh every 5 seconds 

个人的东西,我已经使用Socket.io它的node.js基于运气,但它会采取的护理如何所以每个客户将会获得最好的性能可能。 (内部,它会尝试使用WebSockets,倒在闪光灯插座,然后投票等你拿花式速度new'ish浏览器,同时还支持每个人)在此http://en.wikipedia.org/wiki/Comet_(programming)

+0

在我的情况下,数据以相当高的频率出现(块之间<1s)。我很害怕错过收到答复和发起新请求之间的差距。 – cachance7

+0

然后你正在寻找一个websocket,flash socket或chunked响应。使用类似socket.io(如果可能的话,使用websockets)也可以获得事件驱动的响应。根据你的服务器设置(假设你使用的是apache + php),它可能不会被优化成发送分块响应;而socket.io被设计成具有一个开放的插槽来一次发送小块。 – Will

0

看我有一个网页投票一个使用Ajax的服务器,我已经实现了一个Comet服务器。浏览器向服务器发送一个请求,并在服务器上触发一个事件(在我的情况下,当一个文件完成生成时)只接收一个响应。如果服务器在超时(30秒)后没有响应,它会发送一个空响应。每次客户端收到Ajax响应时,都会立即发送新的请求。

好处是,您不需要频繁地轮询服务器,只要服务器发生事件就会通知您的客户端。