所以我找到了答案,它是服務器發送的事件。它基本上支持瀏覽器一次處理塊的單向HTTP流。這可能有點棘手,因爲一些現有的流庫已經損壞(他們不認爲你在流中有\ n,因此你會得到部分數據),或者幾乎沒有文檔。但是推出自己的產品並不難(一旦你明白了)。在服務器端然後
// file sse_stream.coffee
var Transform = require('stream').Transform;
var util = require('util');
util.inherits(SSEStream, Transform);
function SSEStream(option) {
Transform.call(this, option);
this.id = 0;
this.retry = (option && option.retry) || 0;
}
SSEStream.prototype._transform = function(chunk, encoding, cb) {
var data = chunk.toString();
if (data) {
this.push("id:" + this.id + "\n" +
data.split("\n").map(function (e) {
return "data:" + e
}).join("\n") + "\n\n");
//"retry: " + this.retry);
}
this.id++;
cb();
};
SSEStream.prototype._flush = function(next) {
this.push("event: end\n" + "data: end" + "\n\n");
next();
}
module.exports = SSEStream;
(我用的是快遞),你可以做這樣的事情:
您可以定義sse_transform這樣
sse_stream = require('sse_stream')
app.get '/blob', (req, res, next) ->
sse = new sse_stream()
# It may differ here for you, but this is just a stream source.
blobStream = repo.git.streamcmd("cat-file", { p: true }, [blob.id])
if (req.headers["accept"] is "text/event-stream")
res.type('text/event-stream')
blobStream.on("end",() -> res.removeAllListeners()).stdout
.pipe(
sse.on("end",() -> res.end())
).pipe(res)
else
blobStream.stdout.pipe(res)
然後在瀏覽器端,你可以這樣做:
source = new EventSource("/blob")
source.addEventListener('open', (event) ->
console.log "On open..."
, false)
source.addEventListener('message', (event) ->
processData(event.data)
, false)
source.addEventListener('end', (event) ->
console.log "On end"
source.close()
, false)
source.addEventListener('error', (event) ->
console.log "On Error"
if event.currentTarget.readyState == EventSource.CLOSED
console.log "Connection was closed"
source.close()
, false)
請注意,您需要監聽事件'結束',這是從se rver在變換流的_flush()方法中。否則,瀏覽器中的EventSource會一遍又一遍地請求同一個文件。
請注意,您可以使用服務器端的庫來生成SSE。在瀏覽器端,您可以使用門戶。js處理SSE。我只是拼寫出來,所以你可以看到事情會如何運作。
謝謝你的擡頭。我對oboe.js進行了粗略瀏覽,並查看了他們的流式課程,發現它確實使用了xhr。我試圖通過將xhr的responseText字段設置爲null或「」來清除它的responseText字段,但那不起作用。我不懷疑它會在oboe.js中起作用。它似乎是我描述的黑客的正式版本,在轉移完成之前您開始回調。 – Wilhelm