前一篇讲了请求--响应式API
常见Web API -- 请求-响应式
。
本文就讲另外一种:事件驱动式 Web API。
针对用请求-响应式API,如果服务的数据经常变化,那么响应就可能无法保持新鲜了。开发者如果想与变化的数据保持同步,就只能对API进行polling操作了。
但是如果poll的频率较低,客户端仍有可能无法获得从上次poll到现在所有的数据事件。如果poll的频率较高,还特别浪费资源。
二、事件驱动式 Web API
所以我们需要实时的分享事件的数据,通常使用下面三种机制:WebHook,WebSocket,HTTP Streaming。
2.1WebHooks
WebHook就是一个接收HTTP POST(或GET,PUT,DELETE)的URL。一个实现了WebHook的API提供商就是在当事件发生的时候会向这个配置好的URL发送一条信息。与请求-响应式不同,使用WebHook,你可以实时接受到变化。
下面是Polling和Webhook的比较:
WebHook非常适合于从一个服务器向另外一个服务器分享实时数据。
但是实现WebHook,也引入了新的复杂性:
失败和重试。为了保证WebHook被成功的传输,你需要构建一个可以再发生错误时进行重试操作的系统。
安全性。对于安全的调用REST API,现在的方案都比较成熟;而对于WebHook来说,这方面依然在探索中前进。
防火墙。防火墙后运行的应用可以通过HTTP访问API,但是它们可能无法接收入站的流量。所以这是一个很大的问题。
噪声。通常每个WebHook调用代表了一个事件,但当短时间内发生了成千上万个事件的时候,再通过WebHook来传输,就可能会有噪音。
2.2WebSocket
WebSocket这个协议,它通过一个TCP协议建立一个双向全双工的流式通信。WebSocket通常用在客户端和服务器之间的通信,也可以用在服务器之间的通信。
ASP.NET Core SignalR就是优先使用该协议。
WebSocket支持全双工(服务器和客户端可以同时双向通信),而且开销不高。经常使用的端口式80或443,这样就很容易穿过防火墙了。
WebSocket特别适合于快速的,现场的路i数据和长连接。
如果连接挂掉了,客户端会尝试重新初始化连接。但是WebSocket有一些扩展性的问题,因为如果在线的客户端太多,那么服务器端就需要维持这些客户端打开的连接。
2.3HTTP Streaming
使用请求-响应式API,客户端发送一个请求,服务器端返回一个响应,这个响应的长度是有限的。
而使用HTTP Streaming,服务器端可以在一个由客户端打开的长生存的连接里持续的推送新数据。
为了让数据通过一个可长时间存在的连接上进行传输,有两个方案:
首先可以让服务器把Transfer-Encoding这个Header设为chunked。这表示客户端是按块接收数据的,块与块之间用换行符分割:“\r\n”。
另一个选项是通过Server-Sent Events (SSE)来进行流数据。这个比较适合于浏览器内的客户端,因为这样它们就可以使用标准的EventSource API了。(SignalR在无法使用WebSocket的时候就会使用SSE)
HTTP Streaming用起来好像很容易,但是有个问题,是关于缓存的。客户端和代理经常会有缓存的限制。因为只有达到某个阈值之后,它们才会把数据渲染给应用。
综上,针对事件驱动式Web API:
如果想要进行服务器间的实时事件通信,可以选择WebHooks
如果需要浏览器和服务器间的双向实时通信,可以选择WebSocket
如果需要使用简单的HTTP进行单向通信,可以使用HTTP Streaming