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

什么是监视REST资源更改的RESTful方法?,rest,long-polling,polling,Rest,Long Polling,Polling,如果有一个REST资源我想监视来自其他客户机的更改或修改,那么最好(也是最RESTful的)方法是什么 我这样做的一个想法是提供特定的资源来保持连接的开放性,而不是在资源(还)不存在时立即返回。例如,给定资源: /game/17/playerToMove “抓住”这个资源可能会告诉我,轮到我的对手移动了。与其不断轮询此资源以确定何时轮到我移动,我可能会记下移动编号(比如5),并尝试检索下一个移动: /game/17/move/5 在“普通”REST模型中,对该URL的GET请求似乎会返回40

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

我这样做的一个想法是提供特定的资源来保持连接的开放性,而不是在资源(还)不存在时立即返回。例如,给定资源:

/game/17/playerToMove
“抓住”这个资源可能会告诉我,轮到我的对手移动了。与其不断轮询此资源以确定何时轮到我移动,我可能会记下移动编号(比如5),并尝试检索下一个移动:

/game/17/move/5
在“普通”REST模型中,对该URL的GET请求似乎会返回404(未找到)错误。但是,如果相反,服务器将保持连接打开,直到我的对手开始移动,即:

PUT /game/17/move/5
然后服务器可以返回我的对手放入该资源的内容。这既可以为我提供所需的数据,也可以为我的对手在不需要投票的情况下移动提供某种通知

这类计划是否令人安心?或者它违反了某种REST原则吗?

我发现提出了一个新的HTTP头,“在之后修改时”,它基本上做了相同的事情——服务器等待并保持连接打开,直到资源被修改


我更喜欢基于版本的方法,而不是基于时间戳的方法,因为它不太容易受到竞争条件的影响,并且可以为您提供有关您正在检索的内容的更多信息。对此方法有何想法?

如果您的目标客户端是web浏览器,我建议使用404,因为保持连接打开会主动阻止客户端中对同一域的浏览器请求。这取决于客户多久进行一次民意调查。

您提出的解决方案听起来像,但可能非常有效

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

这样做的好处是速度非常快——一旦服务器有了新数据,客户端就会得到它。它还具有对断开连接的恢复能力,如果客户端断开连接一段时间(您可以在移动一小时后请求
/game/17/move/5
,并立即获取数据,然后移动到
move/6/
,依此类推)

长轮询的问题是,每次“轮询”都会绑定一个服务器线程,这会很快中断Apache之类的服务器(因为它没有工作线程,所以无法接受其他请求)。您需要一个专门的web服务器来处理长轮询请求。。Python模块(一个“事件驱动的网络引擎”)在这方面做得很好,但它比常规的轮询工作更多


在回答您关于Jetty/Tomcat的评论时,我对Java没有任何经验,但它们似乎都使用了与Apache类似的工作线程池系统,因此它也会遇到同样的问题。我确实找到了解决这个问题的方法(对于Tomcat)

这是一种误用错误(因为您请求了/game/x14而不是/game/14,所以如何检测实际的404)。。返回{'error':'no new content'}或者一些问题会小一些..不,因为在执行步骤14之前,资源不存在。。。这是一个合适的404。如果预期的用例是它将在将来出现,我建议改为响应503。根据规范,404不应该在以后自动重试。对于“长时间投票”来说,这似乎效果不错。它是否存在与Apache相同的问题(即工作线程不足)?Tomcat呢?为了避免占用线程,可以使用asp.net异步HTTP处理程序。这会将线程返回到线程池。“使用rest的方法是什么,Srascy?”您可以使用长轮询,或者将rest与websocket服务结合使用,后者将事件发送到客户端。基于版本的方法将使用ETag HTTP头。