如何忽略不耐烦用户的多次点击?[英] How to ignore multiple clicks from an impatient user?

问题描述

我有一个查询来回答远程客户的标准请求.标准,因为它不需要来自服务器外部的参数.每当任何人向 URL 提交请求,例如 http://www.example.com/query, s/he 获取响应正文中 reply.xml 的内容,取决于当时数据库提供的内容.reply.xml 的内容仅在服务器上的数据库内容中更改,并且在任何外部内容上都不会更改就像谁进行查询,输入哪个等,因此不会从客户端获取任何参数.我什至没有检查任何身份验证——我们将所有内容都留给了防火墙.

所以我写了一个 @POST 方法,比如 query() 来调用发布到 http 的此类请求://www.example.com/query,并提供结果.我使用了 Jersey 并且一切都符合规格,除了

请求应该是跨时间排他的.也就是说,一次应该处理一个请求——除非服务器没有运行由我的方法 query() 调用的查询过程,否则后续用户单击应该会收到一条 HTTP 状态为 309 的消息.

如何做到这一点?我尝试让 query() 服务于 @PUT 而不是 @POST 响应,并得到了相同的结果.

也许是关于这个话题的一个天真的问题.但是,对 Restful 服务不是很熟悉.

我可以通过对令牌进行线程化来控制一次只运行一个查询并让同时请求接收 HTTP 309 来做到这一点.但是必须有更好、更简单的方法在服务器上实现这一点.

我使用的是 Tomcat 8,泽西岛 1.19.

TIA.

注意:我已经阅读了 PUT vs POST in REST 以及其他一些有用的内容讨论.

//=======================

编辑:

哪个用户提交查询在任何时候都没有任何区别.

假设 userA 提交了一个查询.当该查询仍在运行时,即在 query() 返回对 userA 的响应之前,userB 提交了一个查询.userB 应该得到一个 309——只是因为当时正在处理一个查询.

无论 userA = userB 还是 userA <> userB 在这里都无关紧要,应该返回 309,因为有一个查询请求,而查询请求已经在运行.这是用户获得 309 的唯一一次.

//================================================

EDIT-2:

我知道带有并发控制的解决方案.我猜有一个使用 Restful 功能.这是一个学术问题.

推荐答案

  • @Koos Gadellaa 说客户端应该阻止是正确的第二个请求,直到响应到达.让我解释一下为什么这是最好的做法.在架构上,它与关注点有关.服务器没有关于为什么两个请求并行到达的上下文感知.因此,它依赖于带外知识来知道并行请求是不好的.任何带外知识都会产生耦合,这意味着如果您更改系统的一个部分的工作方式,则必须更改另一部分.RESTful 架构很受欢迎,因为它们减少了耦合.如果同一用户登录到两个客户端,则系统会中断.您永远不想使用这种类型的客户端-服务器耦合来构建系统.

  • 关于服务器的责任,良好的编码实践开始发挥作用,最好的办法是确保服务不受来自用户的多个并行请求的阻碍.缓存可能是你的朋友.根据查询参数,可以将响应写入磁盘上的缓存文件.客户端将始终使用 HTTP 303 重定向到缓存文件 URL.可以使用 304 Not Modified,这样客户端就不必下载两次答案.在这种情况下,唯一的带外知识是 HTTP 规范的正确实现,该规范明确且稳健.

  • 如果服务超载,相应的响应代码似乎是 503.

    <块引用>

    10.5.4 503 服务不可用

    由于服务器临时过载或维护,服务器当前无法处理请求.这意味着这是一种暂时的情况,经过一段时间的延迟会得到缓解.如果已知,延迟的长度可以在 Retry-After 标头中指示.如果没有给出 Retry-After,客户端应该像处理 500 响应一样处理响应.

         Note: The existence of the 503 status code does not imply that a
         server must use it when becoming overloaded. Some servers may wish
         to simply refuse the connection.
    
  • 既然你是从 我的回复,看来您想知道正确的 RESTful 方法.这将比上面的解决方案更复杂,我猜你不想走这条路,但就是这样.

    <块引用>

    如果服务器需要向客户端传达正在执行的请求以及请求何时完成,则需要为这些概念创建资源.这感觉很奇怪,因为它们的概念存在于 HTTP 中,并且在更高级别重新实现它们很奇怪(架构气味).

    1. 客户端会将 Request 或 Query 资源发布到服务器. 该资源将有一个为空的 Response 属性和一个为空的 Status 属性.服务器将响应一个将 Status 属性设置为"处理"的正文.
    2. 然后,客户端将对该资源执行 GET(可能在此处使用长轮询)以检查更新.
    3. 创建响应后,Response 属性将链接到响应资源或嵌入响应.

    这种方法使用资源来传达正在发生的事情.因此,唯一的带外知识是资源的有效状态.

本文地址:https://www.itbaoku.cn/post/978649.html