HTTP 流和服务器发送的事件有啥区别?

Posted

技术标签:

【中文标题】HTTP 流和服务器发送的事件有啥区别?【英文标题】:What is the difference between HTTP streaming and server sent events?HTTP 流和服务器发送的事件有什么区别? 【发布时间】:2017-07-22 10:40:41 【问题描述】:

我的理解是,HTTP 流式传输涉及客户端发送 HTTP 请求,然后随着时间的推移响应发送的请求,从而允许服务器基本上推送到客户端。在我所读到的内容中,SSE 似乎遵循相同的原则,但更加形式化。这是否接近正确的理解?

我看到了这些问题,但他们并没有真正直接回答我的问题。

HTTP: what are the relations between pipelining, keep-alive and Server Sent Events? What are Long-Polling, Websockets, Server-Sent Events (SSE) and Comet?

我也看过这个https://www.html5rocks.com/en/tutorials/eventsource/basics/#disqus_thread 设置 SSE 的教程,这似乎是我想象的 HTTP 流设置的方式。

【问题讨论】:

【参考方案1】:

SSE 实际上是 HTTP 流的一种形式。它只是一个 MIME 类型为“text/event-stream”的 HTTP 响应,它发送以双换行符结尾的纯文本消息。

SSE 不是以前做不到的事情,但是网站必须使用 WebSocket 连接、AJAX 长轮询、彗星、定期轮询等,现在有了 SSE,API 标准化,实现非常简单。见:

https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

要记住的一件事是,IE 不支持 SSE,包括 Edge 和 IE Mobile:

http://caniuse.com/#feat=eventsource

因此,除非您知道他们使用什么浏览器,否则您还不能真正将其用于更广泛的受众。

【讨论】:

不知道为什么你被否决了,这对我来说听起来不错。谢谢! 那么到底有什么区别呢?这个问题没有回答。如果两者都相同(除了您所说的 mime 类型标头),那么当我们已经拥有 http 流时,甚至引入 SSE 有什么意义?我觉得这个问题还有很多。 @theprogrammer 这是“松散定义”之前的标准化。它还引入了更简单的浏览器 API 来处理这个问题。 MDN 说:When not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6) 截至 2020 年,您对此有何看法?这个限制还存在吗?如果是,那么我们不应该首先使用这种技术,而是更喜欢 WebSocket 连接之类的东西?你怎么看?谢谢! @tonix 在非 HTTP/2 上使用 SSE 时仍然存在多个选项卡 (6) 的限制...【参考方案2】:

恕我直言,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) 
    ...


服务器发送事件的限制:

SSE 事件消耗浏览器打开的连接。 最大打开连接数有限制,不是在浏览器选项卡级别,而是在整个浏览器级别 在我写这篇文章的时候,Chrome 和 Firefox 的值为 6(太低了)。此限制针对每个浏览器 + 域,因此这意味着您可以在所有选项卡上打开 6 个 SSE 连接到 www.example1.com 和另外 6 个 SSE 连接到 www.example2.com。

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 的分块传输编码机制,因为它提供了自己的更高效的数据流传输机制。

【讨论】:

以上是关于HTTP 流和服务器发送的事件有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Web 套接字、长轮询、服务器发送事件和永久帧之间有啥区别?

跨域匿名和使用凭证有啥区别

重放攻击与中间人攻击有啥区别?

PAP和CHAP有啥区别各代表啥意思

POST 和 PUT HTTP 请求有啥区别?

HTTPS和HTTP有啥区别?