使用阻塞REST请求来实现发布/订阅
最近,我被要求调查与电话系统供应商集成的可行性,该供应商希望使用 RESTful Web 服务来提供电话事件(例如线路振铃、分机应答、呼叫清除)。
我指出 REST 是一个请求/响应协议,他们正在执行发布/订阅。他们建议的解决方案是发出 HTTP REST 请求,该请求将被阻止,然后在事件可用或超时时最终响应。
无论哪种方式,都会发出另一个请求来获取下一个事件,依此类推。
这个想法让我感到畏缩,但我确信 iPhone 的“推送”电子邮件就是这样运作的。
这是 REST 的合理使用吗?
I've recently been asked to investigate the feasibility of integrating with a phone system vendor who wants to make phone events (e.g. line ringing, extension answered, call cleared) available using a RESTful web service.
I pointed out that REST is a request/response protocol and they were doing publish/subscribe. The solution they were suggesting was to make an HTTP REST request which would block and then eventually respond if and when an event was available - or time out.
Either way, another request would be made to get the next event and so on ad infinitum.
This idea made me cringe, but I was assured that the iPhone "push" e-mail operates this way.
Is this a reasonable use of REST?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想说它不太适合 REST 架构风格(主要是因为 REST 将其限制为无状态客户端服务器交互)。然而,网络上有大量进行长轮询的解决方案,尽管不符合网络的精神,但它或多或少有效。
首先,关于架构的说明:在 REST 中实现 pub/sub 仅意味着发布者将项目添加到列表中,然后该列表可供订阅者使用。订阅者对列表进行投票。有多种方法可以实现这一点,以确保一次且仅一次,同时维护消息顺序和(一种形式)保证交付(尽管是异步的)。它的扩展性非常好,而且非常有弹性。
我的第一条建议是使其成为可选的,以便无法执行长轮询(或不想)的客户端可以这样做。我什至会说,如果通用客户端(如 Google)默认情况下不会执行长轮询,并且服务器通过特殊的共享方式启动长轮询。客户端和服务器之间的理解。这种共同理解可以是自定义媒体类型或自定义链接关系,甚至是通用客户端不知道的自定义 HTTP 标头。支持长轮询的客户端将被编码为发现长轮询的功能,并在必要时调用它,如果长轮询失败(例如中介以某种方式阻止它),则返回到常规轮询。
我建议不要尝试在 HTTP 之上执行此操作,而是使用非 HTTP 套接字,以免违反 HTTP 的意图并有效地使用 HTTP 作为传输协议。参见彗星。
我的另一条建议是问你的客户必须有多“实时”。如果几秒的延迟是可以接受的,那么您可以进行大量的定期轮询,即使对于大量的客户端也是如此,因为使用定期轮询解决此问题的可缓存性质。
I would say that it doesn't fly well with the REST architectural style (mainly because REST constrains it to stateless client server interactions). However, the web is abundant with solutions that do long polling, and it more or less works, in spite of not being in the spirit of the web.
First, a note on architecture: Implementing pub/sub within REST merely means that the publisher adds items to a list which then is made available to subscribers. Subscribers poll the list. There are ways of crafting this to ensure once-and-only-once while maintaining message order and (a form of) guaranteed delivery, albeit asynchronous. It scales really well, and is really resilient.
My first piece of advice would be to make it optional, so that clients that can't perform long polling (or don't want to) can do so. I would even go so far as to say that if a generic client (like Google) the default would be not to perform long polling, and that the server kicks the long polling in by way of a special shared understanding between your client and the server. That shared understanding could be a custom media type or a custom link relation, or even a custom HTTP header that generic clients wouldn't know about. Clients that do support your long poll would be coded to discover the capabilities of long polling, and invoke it as necessary, falling back to regular polling if the long poll fails (e.g. an intermediary blocks it somehow).
And instead of trying to do this on top of HTTP, I would suggest using a non-HTTP socket for this, to not violate the intentions of HTTP and effectively use HTTP as a transport protocol. See cometd.
My other piece of advice would be to ask the question how "real time" your clients have to be. If a few seconds latency is acceptable then you can do a great deal with regular polling, even for extremely large numbers of clients, due to the cacheable nature of solving this using regular polling.