谷歌云盘使用哪种技术来获取实时更新?

64

Google Drive使用哪种技术来进行实时编辑?

当我在多个用户访问的Google Drive文档中输入时,Chrome开发者工具网络选项卡显示没有WebSockets。

我发现最常见的两种AJAX调用类型在URL中分别有"bind?"或者"save?"。"save?" POST请求在我每次输入时都会被发送,这很有意义-普通的AJAX用于将更新发送到服务器。

当另一个用户输入时,最近的"bind?" GET调用保持打开状态,并且通过该连接传输的数据量增加。定期地,“bind?”被关闭并打开新的,“bind?”的逻辑似乎是持续时间和数据大小的某个函数。

由于当服务器发送更新时不会完成响应,因此这不是长轮询。

由于内容类型为"text/plain"而不是"text/stream",因此这似乎不是服务器推送事件。

Google正在做什么?如果可以的话,我该如何尝试实现这一点?

Chrome Dev Tools - editing a Google Drive document


Google日历使用相同的技术吗? - Jitendra Pal - JP
2个回答

84

Google Drive实时更新解决方案的名称是什么(例如"长轮询"或"sockets")?

迄今为止它没有名称。我会称之为 "no-polling",以与轮询和长轮询形成对比。

使用轮询,客户端会定期发送查询以获得新数据。

使用长轮询,客户端查询数据,服务器保留请求,并在有更新时通过响应结束返回更新。

No-polling(即Google Drive所做的)利用了浏览器可以在请求完成之前从请求体中读取数据的特性。因此,随着协作者进行更多输入和编辑,服务器将更多数据附加到当前请求。如果满足某些限制条件(内容长度或请求持续时间),则请求将完成,客户端会向服务器发起一个新请求。

如何尝试实现这个解决方案?

客户端向服务器发送更新:这可以通过普通的POST请求完成。

客户端订阅来自服务器的更新:

  • 客户端发送GET请求更新流,然后在响应完成之前开始读取响应体。

    XHR对象可以在请求完成之前发出progress事件。 可以使用 xhr.responseText 访问(部分)响应。~~截至2016年5月,尚无简单的方法使用fetch观察进度yet。~~ 使用fetch时,可以通过消耗res.body ReadableStream来观察进度。

  • 当当前请求结束时,客户端应该启动一个新的请求。

服务器必须:

  • 追踪订阅了哪些更新流的客户端。
  • 当针对特定更新流的请求到达时,将数据写入响应,但在数据量变大或超时时才完成响应。
"No-polling" 在我看来比 "long-polling" 更优秀,尽管我没有多少使用经验。在更新速率恒定的情况下,长轮询需要在延迟和消息大小之间做出权衡,而 "no-polling" 则不需要这样做。长轮询的另一个缺点是它可能会导致许多 HTTP 请求,每次请求都要支付 HTTP 的开销。
与 WebSocket 相比,"no-polling" 最大的优势在于它被每个浏览器支持,尽管 WebSocket 的支持也相当不错 - IE10+

1
我认为Facebook也做了类似的事情。试着与一些人进行交谈:它在抓取更多数据的同时维持一个持久的HTTP连接。 - helsont
3
当前的 fetch 规范表明 res.body 是一个 ReadableStream,可以让你使用 fetch 来监测进度。 - kimamula
1
这非常有趣...我以前从未听说过这种方法。 - Daniel Waltrip
有没有已经实现这个的框架?或者有没有实现这个的代码片段?@MaxHeiber - Mayank Singh Fartiyal
1
据我所见,他们似乎已经转换为“标准”长轮询策略,即每次发送数据时请求都会关闭。 - Cédric Nirousset
显示剩余2条评论

5

这里所描述的无轮询技术类似于 "服务器发送事件 - SSE",其中客户端通过发送带有 "text/event-stream" 内容类型的 HTTP GET 请求。 服务器保持对请求的控制,并在需要时向客户端发送响应。 它是持久性的,但与WebSocket不同,WebSocket是双向通信,而SSE是单向通信(只有服务器向客户端发送有效载荷/消息)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接