什么是监视REST资源以进行更改的RESTful方法?

时间:2009-01-02 03:26:48

标签: rest long-polling polling

如果有一个REST资源我想要监视来自其他客户端的更改或修改,那么最好的(也是最RESTful)方式是什么?

我这样做的一个想法是提供特定的资源来保持连接打开,而不是在资源不存在的情况下立即返回。例如,给定资源:

/game/17/playerToMove

这个资源上的“GET”可能会告诉我轮到我的对手了。我可能会注意到移动号码(比如5)并尝试检索下一步行动,而不是不断地轮询这个资源以找出轮到我移动的时间:

/game/17/move/5

在“正常”REST模型中,似乎对此URL的GET请求将返回404(未找到)错误。但是,如果相反,服务器保持连接打开,直到我的对手发挥他的举动,即:

PUT /game/17/move/5

然后服务器可以将我的对手PUT的内容返回到该资源。这既可以为我提供我需要的数据,也可以提供一些关于我的对手何时移动而不需要投票的通知。

这种方案是RESTful吗?或者它是否违反了某种REST原则?

3 个答案:

答案 0 :(得分:25)

您提出的解决方案听起来像long polling,效果非常好。

您将请求/game/17/move/5,服务器将不会发送任何数据,直到移动5完成。如果连接断开,或者您有超时,则只需重新连接,直到获得有效的响应。

这样做的好处是它非常快 - 只要服务器有新数据,客户端就会得到它。它还具有恢复连接的弹性,并且在客户端断开一段时间后可以正常工作(您可以在移动一小时后请求/game/17/move/5并立即获取数据,然后转到move/6/等等)

长轮询的问题是每个“轮询”都会绑定一个服务器线程,这会快速破坏Apache之类的服务器(因为它耗尽了工作线程,因此无法接受其他请求)。您需要一个专门的Web服务器来提供长轮询请求.Python模块twisted(一个“事件驱动的网络引擎”)非常适合这种情况,但它比常规轮询更多的工作.. < / p>

在回答你对Jetty / Tomcat的评论时,我对Java没有任何经验,但似乎他们都使用类似的工作线程池系统到Apache,所以它会遇到同样的问题。我确实发现this post似乎正好解决了这个问题(对于Tomcat)

答案 1 :(得分:2)

我发现this article提出了一个新的HTTP标头,“When-Modified-After”,基本上做同样的事情 - 服务器等待并保持连接打开,直到资源被修改。

我更喜欢基于版本的方法,而不是基于时间戳的方法,因为它不太容易出现竞争条件,并且会为您提供有关您正在检索的内容的更多信息。对这种方法有什么想法吗?

答案 2 :(得分:2)

如果您的目标客户端是Web浏览器,我建议使用404,因为保持连接打开可以主动阻止客户端中的浏览器请求到同一个域。由客户决定投票的频率。