📞7. 实时通信

作者:Bryan Cooksey 发布日期:2014年4月22日

第六章中,我们通过构建自己的API并探索一些实际示例来学习了如何设计API。现在,我们已经积累了很多宝贵的知识,是时候开始利用它了。在本章中,我们将学习通过API实现实时通信的四种方式。

集成

为了为我们的讨论做好铺垫,让我们回顾一下API为什么有用。在第一章中,我们说API使得在两个系统(网站、桌面、智能手机)之间共享数据变得容易。直接的共享使我们能够将系统连接在一起形成集成(integration)。人们喜欢集成,因为它们使生活更轻松。通过集成,您可以在一个系统中做某些事情,另一个系统会自动更新。

为了我们的目的,我们将将集成分为两个广泛的类别。第一个称为“客户端驱动”,其中一个人与客户端交互,并希望服务器的数据更新。另一个称为“服务器驱动”,其中一个人在服务器上执行某些操作,并需要客户端知道这个变化。

“客户端驱动”和“服务器驱动”是我们的术语,所以如果您在开发人员面前使用其中一个术语并得到一片茫然,不要感到惊讶。如果您想要即时的可信度,可以提到轮询或Webhooks。

将集成分为这种方式的原因归结为一个简单的事实:客户端是唯一能够发起通信的一方。请记住,客户端发出请求,服务器只是响应。这种限制的一个结果是,从客户端发送更改很容易,但在相反的方向上很困难。

客户端驱动集成

为了说明客户端驱动集成为什么容易,让我们转向我们可靠的比萨店和其用于订购比萨的API。假设我们发布了一个使用该API的智能手机应用程序。在这种情况下,比萨店的API是服务器,智能手机应用程序是客户端。顾客使用该应用程序选择比萨,然后点击按钮下订单。按钮被按下后,应用程序知道它需要向比萨店的API发出请求。

更一般地说,当一个人与客户端交互时,客户端准确地知道数据何时发生变化,因此它可以立即调用API通知服务器。没有延迟(因此是实时的),并且该过程非常高效,因为每个人的操作只需要一个请求。

服务器驱动集成

一旦订单被下达,顾客可能想要知道比萨何时准备好。我们如何使用API向他们提供更新呢?嗯,这有点困难。顾客与制作比萨无关。他们正在等待比萨店准备比萨并更新订单状态。换句话说,数据在服务器上发生变化,客户端需要知道这一点。然而,如果服务器不能发出请求,我们似乎陷入了困境!

解决这类问题是我们利用集成的第二类别的地方。软件开发人员使用了许多解决方案来绕过仅限客户端请求的限制。让我们看看每种解决方案。

轮询(Polling)

当客户端是唯一能够发出请求的一方时,使其与服务器保持同步的最简单解决方案是客户端简单地请求服务器的更新。这可以通过重复请求相同的资源来实现,这种技术被称为轮询。

对于我们的比萨店,轮询订单状态可能如下所示。

在这种方法中,客户端发出请求(轮询)的频率越高,客户端与实时通信越接近。如果客户端每小时轮询一次,最坏的情况下,服务器上的更改发生后,客户端可能需要等待一小时才能知道。如果每分钟轮询一次,客户端和服务器将有效地保持同步。

当然,这种解决方案有一个很大的缺陷。它非常低效。客户端发出的大部分请求都是浪费的,因为没有任何变化。更糟糕的是,为了更快地获取更新,轮询间隔必须缩短,导致客户端发出更多的请求,效率更低。这种解决方案不具备良好的可扩展性。

长轮询(Long Polling)

如果请求是免费的,那么没有人会关心效率,每个人都可以使用轮询。不幸的是,处理请求是有代价的。为了处理更多的请求,API需要使用更多的服务器,这就需要更多的成本。将这种繁琐的情况扩展到谷歌或Facebook这样的规模,您将为低效性付出很高的代价。因此,人们已经付出了很多努力来优化客户端接收服务器更新的方式。

其中一种优化是长轮询。长轮询是在轮询的基础上进行的一种方法,但有所不同:服务器不会立即响应。相反,服务器会等待直到有变化发生,然后才会响应更新。

让我们重新审视上面的轮询示例,但这次使用一个使用长轮询技巧的服务器。

这种技术相当聪明。它遵守了客户端发起初始请求的规则,同时利用了服务器可以缓慢响应的事实。只要客户端和服务器都同意服务器将保持客户端的请求,并且客户端能够保持与服务器的连接,它就可以工作。

尽管长轮询非常有创意,但它也有一些缺点。我们将跳过技术细节,但有一些问题,比如服务器可以同时保持多少个请求,或者如果客户端或服务器失去连接该如何恢复。目前,我们可以说对于某些场景,轮询的任何形式都不足够。

Webhooks

如果轮询被排除在外,一些有创意的软件开发人员想到了“如果我们所有的麻烦都是因为只有客户端发出请求,为什么不取消这个规则呢?”于是他们这样做了。结果就是Webhooks,一种允许客户端同时发出请求和监听请求的技术,使得服务器可以轻松地向客户端推送更新。

如果这听起来像作弊,因为现在服务器也可以向客户端发出请求,不要担心,您没有被欺骗。Webhooks之所以起作用,是因为客户端也变成了一个服务器!从技术角度来看,有时候很容易将客户端的功能扩展到同时监听请求,实现双向通信。

让我们来看看Webhooks的基本原理。在其最简单的形式中,Webhooks要求客户端提供一个回调URL,用于接收事件,而服务器需要有一个地方让人们输入该回调URL(Callback URL)。然后,每当服务器上发生变化时,服务器可以向客户端的回调URL发送请求,以通知客户端有关更新的信息。

对于我们的比萨店来说,流程可能如下所示。

这个解决方案非常好。服务器上的变化会即时发送到客户端,因此您可以进行真正的实时通信。此外,Webhooks非常高效,每次更新只有一个请求。

订阅Webhooks

在Webhooks的基础上,出现了各种解决方案,旨在使设置过程具有动态性,并且不需要人手动在服务器上输入回调URL。您可能会听到像HTTP Subscriptions Specification、Restful Webhooks、REST Hooks和PubSubHubbub这样的名称。所有这些解决方案都试图定义一个订阅过程,客户端可以告诉服务器它感兴趣的事件以及要发送更新的回调URL。

每个解决方案对问题有稍微不同的理解,但总体流程如下。

基于订阅的Webhooks有很大的潜力。它们高效、实时,并且易于人们使用。类似于REST的迅猛发展,这个潮流正在兴起,并且越来越常见的API支持某种形式的Webhooks。

然而,预计在可预见的未来,轮询和长轮询仍然会有一席之地。并非所有客户端都可以充当服务器。智能手机是一个很好的例子,技术限制排除了Webhooks作为可能性。随着技术的进步,将会出现新的想法,以便更轻松地在各种设备之间实现实时通信。

第7章小结

在本章中,我们将集成分为两个广泛的类别:客户端驱动和服务器驱动。我们看到了如何使用API在两个系统之间提供实时更新,以及其中的一些挑战。

我们学到的关键术语是:

  • 轮询(Polling):以短时间间隔重复请求资源

  • 长轮询(Long Polling):轮询,但延迟响应;提高效率

  • Webhooks:当客户端给服务器提供回调URL时,服务器可以实时发布更新

  • 订阅Webhooks(Subscription Webhooks):用于自动设置Webhooks的非正式名称

接下来

在本课程的最后一章中,我们将看看将API设计转化为可工作软件所需的步骤。

最后更新于