第7章:实时通信
第6章中,我们通过构建自己的API学习了如何设计API,还看了几个实际的例子。现在,我们有了很多来之不易的知识,是时候获取收益了。我们准备学习如何让API工作。本章中,我们学习通过API进行实时通信的四种方式。
集成
为了给我们的讨论做好准备,我们来复习以下为什么API是有用的。回到第1章,我们说过API让两个系统(网站,台式机,智能手机)之间共享数据变得简单。直接共享允许我们将两个系统连接在一起形成一个集成系统。人们喜欢集成系统因为它们让生活更容易。有了集成系统后,你可以在一个系统里做一些事情,另一个系统会自动更新。
为了达到我们的目的,我们将集成分成两大类。第一个我们称之为“客户端驱动”,人们与客户端交互,然后希望更新服务器的数据。另一个我们称为“服务器驱动”,人们在服务器上做些事情,需要将这些更改通知给客户端。
将集成按照这种方式进行划分的原因归结起来就是这样一个事实:只有客户端可以发起通信。请记住,客户端发送请求,服务器只是进行响应。这种限制的一个后果就是修改可以很容易的从客户端发送到服务器,反过来就很难了。
客户端驱动的集成
为了说明为什么客户端驱动的集成容易实现,我们转到披萨店,看看订购披萨的API。在这种情境下,披萨店API是服务器,智能手机app是客户端。顾客使用app选择披萨,然后点击按钮下订单。当按钮被按下的时候,app知道它需要发送一个请求给披萨店API。
通俗的讲,当一个和客户端进行交互的时候,客户端可以准确的知道数据发生了改变,然后它可以立刻呼叫API,让服务器知道这个改变。这里是没有延时的(所以是实时的),并且处理的效率非常高因为用户的每一个动作只需要一个请求就可以了。
服务器驱动的集成
下了订单之后,顾客可能想知道披萨什么时候能做好。我们如何利用API提供这些最新的消息呢?好吧,这个有点难了。顾客和制作披萨没有任何关系。他们就是等待披萨店准备披萨和更新订单状态。换句话说,数据的修改是在服务器,客户端需要知道这个改变。但是,如果服务器不能发送请求的话,看起来我们就被困住了!
解决这种类型的问题就是我们使用第二类集成的地方了。有很多解决方案软件供开发者使用来回避只能由客户端发送请求的局限。我们来逐个看看。
询问
当只能由客户端发送请求的时候,让客户端和服务器同步的最简单的解决方法就是让客户端向服务器询问修改。这个可以通过重复的请求相同的资源来实现,这种技术就是我们所知道的询问。
针对我们的披萨店,询问一个订单的状态可能是像下面这样。
在这种方法中,客户端发送请求(询问)越频繁,就越接近实时通信。如果客户端每小时询问一次,那么在最坏的情况下,服务器发生改变和客户端察觉到这个改变之间就有一个小时的延时。如果每分钟询问一次的话,客户端和服务器就可以有效的保持一致。
当然,这种方案有一个大的缺陷。它的效率不高。客户端的大部分请求都是浪费的,因为没有发生改变。更糟糕的是,为了更迅速的获取修改,就必须减少询问的间隔,导致客户端发送更多的请求,效率就变得更低。这种方案的伸缩性不好。
长询问
如果请求没有代价,那就没有人会在意效率,所有人都使用询问就可以了。不幸的是,处理请求是有成本的。为了让API处理更多的请求,需要使用更多的服务器,这就需要更多的钱。把这种麻烦的情况扩大到Google或Facebook那种规模,你就要为这种低效率支付非常多的钱。因此,人们做了很多努力来优化客户端从服务器获取更新的方式。
有一种基于询问的优化方案,叫做长询问。长询问的思路是一样的,也是客户端重复向服务器询问修改,但是有一点不同:服务器不是立刻响应。取而代之的是服务器会等待到某个事件发生才会将修改作为响应返回。
我们重新看一次上面的询问的例子,但是这次服务器使用长询问的技巧。
这个技术相当聪明。它遵循了客户端发起初始请求的规则,同时利用了这样一个事实,即没有规定说服务器不能延迟响应。只要客户端和服务器都同意服务器保持客户端的请求,并且客户端可以让自己的连接保持对服务器开放,该技术就可以工作。
即便长询问已经足够聪明了,但还是有不足。我们会跳过技术细节,但是还是有些东西我们需要关心,比如服务器可以同时保持多少个请求,如果客户端或服务器丢失了连接如何进行恢复。目前来说,我们认为对于某些情况来说,这两种方式都不够好。
webhooks
将询问排除之后,一些有创造力的软件开发者考虑,“如果我们所有的麻烦都是因为只能由客户端发送请求,为什么不把这条规则去掉呢?”所以他们就这么做了。结果就是webhooks,在这种技术中,客户端发送请求,然后监听请求,允许服务器轻松的向它们推送更新。
如果这听起来像是会话,因为现在我们让服务器向客户端发送请求,别着急,你没说错。让webhooks工作的正是这一点,客户端也成为服务器了!从技术的角度来看,有时候扩展客户端的功能让它也能监听请求,从而实现双向对话是很容易的。
我们来看一下webhooks的基本原理。在简单形式下,webhooks需要客户端提供一个可以接收事件的回调URL,服务器需要有一个地方让人输入这些URL。然后,当服务器上发生改变的时候,服务器可以向客户端的回调URL发送请求,从而让客户端知道更新。
对于我们的披萨店,流程可能是这样的。
这个方案非常棒。服务器上的改变立刻被发送给客户端,这样就有了真正的实时通信。还有webhooks非常有效率,因为每个更新只需要一个请求。
订阅Webhooks
基于webhooks的思想,已经有多种方案致力于让流程自动完成,而不需要有人在服务器上手工输入回调URL。你可能听过HTTP Subscriptions Specification, Restful Webhooks, REST Hooks, 和PubSubHubbub之类的东西。这些方案想要做的就是定义一个订阅流程,使得客户端可以告诉服务器自己对哪些事件感兴趣,以及更新应该发送给哪个回调URL。
每个方案对这个问题的看法都有些微的不同,但是普遍的流程是这样的。
基于订阅的webhooks有很多优势。它们高效,实时并且容易使用。和普遍采用REST一样,webhooks也成为了一种潮流,让API支持某种形式的webhooks会越来越普遍。
然而,在可预料的将来,询问和长询问仍会有一席之地。不是所有的客户端都可以像服务器一样工作。手机就是一个很好的例子,技术的约束使得webhooks称为不可能。随着技术的发展关于如何轻松的在不同类型的设备之间进行实时通信会有新的思想出现。
译自