HTTP2 - 如何拥有类似 WebSocket 的功能(Keep-Alive、EventSource 等)
Posted
技术标签:
【中文标题】HTTP2 - 如何拥有类似 WebSocket 的功能(Keep-Alive、EventSource 等)【英文标题】:HTTP2 - How to have WebSocket-like functionality (Keep-Alive, EventSource, etc.) 【发布时间】:2018-05-26 13:39:04 【问题描述】:想知道如何在 Node.js 中建立客户端和服务器之间的持久连接。
持久连接应该能够从双方来回发送请求。似乎它需要一种机制来描述每个请求,例如 \r\n
如果请求是 JSON,但如果之前已经完成,则不确定这里有什么最佳实践。想知道 web-sockets 是如何处理这个问题的。
Mozilla 说 Keep-Alive 不应该在生产中使用,所以想知道这是否仍然适用于 HTTP2。
使用EventSource,您可以接收服务器事件,但想知道是否有办法添加客户端事件以发送到服务器。
最后,我想为 WebSockets 之类的双向通信设置一个简单的设置,但我不确定 HTTP2 的最佳实践以及是否应该使用 WebSockets 来完成。我宁愿在没有 websockets 的情况下尝试这样做。
https://daniel.haxx.se/blog/2016/06/15/no-websockets-over-http2/【问题讨论】:
为什么不使用 websockets?借助 socket.io 或 SockJS 等库,可以构建它们以支持旧平台 只是想了解它是如何工作的。 如果您要在应用程序之间而不是在 Web 浏览器上传递消息,请查看 grpc。它为您提供 http2 和类型安全的服务定义等等。 【参考方案1】:恕我直言,我相信您错误地认为 HTTP/2 连接是特定于页面的。
实际上,HTTP/2 连接通常是浏览器范围的连接。 HTTP/2 push
不可能知道哪个页面/选项卡将使用数据(可能不止一个)。
另外,请参阅here 讨论,其中包含关于为什么 HTTP/2 不能(或不应该)用作 Websocket 替代方案的无数原因。
另一方面,如果 HTTP/2 被“承诺”并且 Websocket 不可用,那么轮询可能是一种选择。
使用 HTTP/2 轮询将比使用 HTTP/1.1 轮询更加资源友好,尽管由于额外的标头和身份验证数据,它仍然比 Websocket 推送(或轮询)昂贵得多(它也会减少安全性,但这可能是没有人真正关心的事情)。
附言
基于 HTTP/2 的 Websockets
除非 HTTP/1.1 被淘汰,否则这不是问题(事实上,恕我直言,这是故意的,而且很好)。
的确,HTTP/2 连接不能“升级”(更改)为 Websocket 连接,也不能隧道 Websocket 数据,但这绝对没有任何意义。
新的 Websocket 连接使用现有的 HTTP/1.1 升级握手,就是这样。
任何支持 Websockets 的 HTTP/2 服务器都将支持握手。
保持活动状态
Mozilla 对非标准的Keep-Alive
标头发出警告。但是,绝对推荐 HTTP/1.1 的 Connection: keep-alive
标准(这也是 HTTP/1.1 客户端的默认值)。
SSE(服务器发送事件)
SSE 早于 Websockets,它们在社区中并没有引起太大的关注,而 Websockets 被采用了。
想知道是否有办法添加客户端事件以发送到服务器
简单 - 发送 HTTP 请求。可以通过 SSE 异步接收回复。
我更喜欢 Websockets。就服务器端而言,我发现它们更易于管理和编码。
【讨论】:
Websockets 和 HTTP/2 不能很好地混合在一起,如果你想要一个 HTTP/2 上的站点并在同一个域上包含一个 websocket 连接,那就是一个问题。目前这不起作用,因此唯一的选择是暂时禁用 HTTP/2 或将 websocket 连接移动到不同的域。希望随着基于 HTTP/2 的 websockets 在正式规范的道路上顺利进行排序。 @BazzaDP ,我认为您遇到的问题是特定于服务器的。 HTTP/2 和 Websockets 可以在同一个域名上愉快地生活,使用同一个后端应用程序,完全没有问题。当应用服务器不支持 HTTP/2(而且似乎很多不支持)时,这很容易使用代理 Web 服务器来实现,例如 nginx,它使用 HTTP/1.1 将请求转发到应用服务器,也可以设置为直接响应静态文件请求。这是一种非常常见的设置,并且大多数应用程序服务器无论如何都在代理后面运行,用于负载平衡和 TLS 协商。 如果您想知道消息通过 HTTP/2 转到哪个选项卡,您可以使用流标识符,不是吗? @sudo 我不确定我是否理解您的评论。 HTTP/2 连接是浏览器范围的,它们不属于任何特定的选项卡/窗口。 AFAIK,HTTP/2push
语义不能针对特定选项卡... ID 如何帮助解决这个问题?
@sudo ,哦,谢谢你解释你的问题。答案是不。新的push
(或确切地说是 PUSH_PROMISE)不包含有关“相关”流 ID 的任何信息。 The stream ID is totally new and unrelated to any previous request.以上是关于HTTP2 - 如何拥有类似 WebSocket 的功能(Keep-Alive、EventSource 等)的主要内容,如果未能解决你的问题,请参考以下文章