在我看来,HTTP2服务器推送事件比HTTP流媒体具有更丰富的特性。
在仅有单向数据流(服务器 -> 客户端)的情况下,客户端可以基于后端事件进行编排,因此服务器推送事件可能是个不错的选择。
例如:
# ---------- client side -----------
const eventSource = new EventSource("//your-api/workflow/state");
eventSource.addEventListener("queued", function(event) {
...
}
eventSource.addEventListener("started", function(event) {
...
}
eventSource.addEventListener("failed", function(event) {
...
}
eventSource.addEventListener("success", function(event) {
...
}
Server sent events 的限制:
- SSE事件消耗浏览器打开的连接。
- 在整个浏览器范围内有最大打开连接数限制,而不是在浏览器选项卡级别上。
- 截至我编写此文时,Chrome和Firefox将其设置为6(太低了)。此限制是每个浏览器 + 域名的限制,这意味着您可以在所有标签中打开6个与www.example1.com相关的SSE连接,以及另外6个与www.example2.com相关的SSE连接。
HTTP流:
有很多用例中HTTP流可能会非常有用。如果我们只对从服务器传输的消息流感兴趣,那么这种方法就非常方便了。
示例场景:
假设我们想要向客户端流式传输日志文件内容。无论是一个巨大的文件还是文件内容不断更新并且我们希望将其发送到客户端(例如日志尾巴)。在这种情况下,HTTP流(Transfer-Encoding: chunked
)就可以满足我们的需求。
# ---------- client side -----------
const streamRequest = (url) => {
fetch(url).then(function (response) {
let reader = response.body.getReader();
let decoder = new TextDecoder();
return readData();
function readData() {
return reader.read().then(function ({value, done}) {
console.log(value)
if (value) {
let newData = decoder.decode(value, {stream: !done});
console.log(newData);
}
if (done) {
console.log('end of stream');
return;
}
return readData();
});
}
});
}
流响应的限制:
- 对于流响应(分块),HTTP/2不支持HTTP 1.1的分块传输编码机制,因为它提供了自己更高效的数据流传输机制。