HTTP / 2是否使websocket过时?
我正在学习HTTP / 2协议。 这是一个小消息帧的二进制协议。 它允许在单个TCP连接上进行stream复用。 从概念上来说,它与WebSockets非常相似。
有没有计划过时的websockets,并用某种无头的HTTP / 2请求和服务器发起的推送消息取代它们? 或者WebSockets会补充HTTP / 2吗?
从我所理解的HTTP / 2不是websocket的替代品,而是旨在标准化SPDY协议。
在HTTP / 2中,在场景后面使用服务器推送来改善客户端从浏览器加载的资源。 作为开发人员,您在开发过程中并不关心它。 但是,使用Websocket,开发人员可以使用能够消耗和推送唯一全双工连接的API。
这些不一样的东西,它们应该相互补充。
我说Nay(Websockets不是过时的)。
第一个也是最经常被忽略的问题是HTTP / 2推送是不可执行的,并且可能被代理,路由器,其他媒介甚至浏览器忽略 。
即(来自HTTP2草案):
中间人可以接收来自服务器的推送,并select不转发给客户端。 换句话说,如何利用推送的信息取决于中介。 同样,中介可能会select额外推送客户端,而不需要服务器采取任何行动。
另外,HTTP / 2连接会在一段时间后closures。
这个标准确实规定:
HTTP / 2连接是持久的。 为了获得最佳性能,期望客户端在确定不需要与服务器进一步通信(例如,当用户从特定网页导航离开时)或直到服务器closures连接之前不会closures连接。
但…
我们鼓励服务器尽可能保持打开的连接, 但必要时允许终止空闲连接 。 当任一端点selectclosures传输层TCP连接时,终止端点首先应该发送一个GOAWAY(6.8节)帧,以便两个端点可以可靠地确定以前发送的帧是否已经被处理并正常地完成或终止了任何必要的剩余任务。
即使相同的连接允许在打开内容时推送内容,即使HTTP / 2解决了由HTTP / 1.1“保持活动”引入的一些性能问题… HTTP / 2连接也不会无限期地保持打开。
一旦closures,网页也不能重新启动一个HTTP / 2连接(除非我们已经回到了长时间的状态)。
答案是不。 两者之间的目标是非常不同的。 甚至还有一个通过HTTP / 2的WebSocket的RFC,它允许你通过一个HTTP / 2 TCPpipe道build立多个WebSocket连接。
基于HTTP / 2的WS将比任何更多的性能导向。
每个内核每秒可以接收25m HTTP / 2个数据包,而只有980k HTTP / 1.1数据包显示你的速度。
注意:HTTP / 1的两个最昂贵的操作是1)find头部的长度,2)降低字段名称的大小。 两者都要求您读取和parsing标题中的每个字节。 HTTP / 2修正了这两个问题。
https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01
在读完HTTP / 2规范后 ,我认为HTTP / 2在大多数情况下都会使用过时的websocket,但也许并不是全部。
PUSH_PROMISE
(俗称服务器推送)在这里不是问题。 这只是一个性能优化。
浏览器中Websockets的主要用例是启用数据的双向stream式传输。 所以,我认为OP的问题是HTTP / 2在浏览器中是否能够更好地实现双向stream式传输,我认为是的。
首先,它是双向的。 只要阅读stream部分的介绍:
“stream”是在HTTP / 2连接中在客户端和服务器之间交换的帧的一个独立的双向序列。 stream有几个重要特征:
单个HTTP / 2连接可以包含多个同时打开的stream,其中来自多个stream的端点交织帧。
stream可以单独build立和使用,也可以由客户端或服务器共享。
stream可以由任一端点closures。
像这样的文章(链接在另一个答案)是错误的HTTP / 2的这方面。 他们说这不是比迪。 看,有一件事情是不能用HTTP / 2发生的:连接打开后,服务器不能启动普通stream,只能推送stream。 但是,一旦客户端通过发送一个URL请求来打开一个stream,双方都可以在任何时候发送dataframe。 如果您只需要一个stream,客户端只需发送一个“Get me all the data”请求,并在会话的其余部分收听。 这与websocket没有什么不同:客户端必须在服务器可以发送数据之前发起websocket升级请求。 在HTTP / 2和Websocket中,一旦客户端通过请求数据来启动泵,双方都可以随时通过持久套接字发送帧 – 完全双向。 HTTP / 2的这种“只有一种stream”的可能性只是一个退化的基本情况,如果忽略或不想使用HTTP / 2实现的某些额外function,如stream多路复用,你会得到什么。
复用是重要的。 与websockets不同,HTTP / 2定义了自己的多路复用语义:stream是如何获得标识符的,以及帧如何传输stream的标识。 HTTP / 2还定义了stream优先化stream的stream控制语义。
(哦,是的,那篇错误的文章也说Websocket标准是多路复用的,不是的,不是很难发现,只要打开Websocket RFC 6455并按⌘-F键入“multiplex”就可以了。你读了之后
该协议旨在是可扩展的; 未来版本可能会引入其他概念,如复用。
你会发现有2013年的Websocket多路复用草案扩展名 。 但是我不知道哪些浏览器,如果有的话,支持。 我不会试图在这个扩展的后面build立我的SPA webapp,特别是在HTTP / 2来临的时候,支持可能永远不会到达)。
多路复用正是您每当打开一个双向websocket(例如,为被动更新的单页应用程序供电)时通常必须做的事情。 我很高兴它是在HTTP / 2规范,照顾一劳永逸。
如果你想知道HTTP / 2可以做什么,只要看看gRPC。 gRPC是通过HTTP / 2实现的。 具体来看gRPC提供的半双工和全双工stream选项。 (请注意,gRPC目前不在浏览器中工作,但实际上是因为浏览器(1)不会将HTTP / 2帧暴露给客户端javascript,并且(2)通常不支持使用的拖车gRPC规范)
websockets在哪里还有一席之地? 如果你不需要任何额外的HTTP / 2规格(这是一个巨大的,复杂的规格),那么websockets可能会更好。 挥舞我们的手执行困难,我相信遵守websocket协议总是比HTTP / 2计算成本低 – HTTP / 2只是要求你做更多的东西。
帧的大小是非常可比的。 与HTTP / 2的固定长度相比,Websocket帧要小一些,每帧需要2-14字节的开销。因为websocketselect了一个可变长度的头,它可以对较大的帧进行编码(每帧高达2 ^ 64-1位vs HTTP / 2 2 ^ 24-1位/帧)。 所以,如果你需要一个套接字来吸引一些没有很多仪式的东西,像我不知道,也许是video框架,然后websockets可能仍然是有道理的。 对于大多数用例,特别是与网页相关的东西,我认为HTTP / 2看起来像是前进的方向。
那么,引用这个InfoQ文章:
那么答案显然是否定的,原因很简单:正如我们上面看到的那样,HTTP / 2引入了服务器推送(Server Push),它使服务器可以主动向客户端caching发送资源。 但是,它并不允许将数据推送到客户端应用程序本身。 服务器推送只能由浏览器处理,不要popup到应用程序代码,这意味着应用程序没有API来获取这些事件的通知。
因此,HTTP2推送实际上是在浏览器和服务器之间的事情,而Websockets确实公开了可以由客户端(如果它在浏览器上运行的话)和用于传送实时数据的应用程序代码(在服务器上运行)使用的API。
消息交换和简单的stream(不是audio,videostream)可以通过Http / 2多路复用和WebSocket完成。 所以有一些重叠,但WebSockets有很好的协议,很多框架/ API和较less的头部开销。 这里是关于这个话题的好文章 。
我不这么认为,如果推/拉和全双工可用作为http / 2的一部分,那么为什么我应该build议使用WebSocket,并明确额外的开销。 我应该说是的,它肯定会过时的WebSocket