长时间运行的 Wicket Ajax 请求

发布于 2024-08-24 02:09:32 字数 382 浏览 4 评论 0原文

我的 Wicket 应用程序中偶尔会出现一些长时间运行的 AJAX 请求。发生这种情况时,应用程序基本上无法使用,因为后续 AJAX 请求将排队等待在当前请求之后同步处理。我希望请求在一段时间后终止,无论是否返回响应(我有一个用户要求,如果发生这种情况,我们应该向用户显示错误消息并继续)。这就提出了两个问题:

  1. 有没有办法指定一个 特定于 AJAX 的超时 或所有 AJAX 请求?
  2. 如果没有,有什么办法可以杀死当前的请求吗?

我查看了 wicket-ajax.js 文件,没有看到任何提及请求超时的内容。

我什至尝试在客户端超时后重新加载页面,但不幸的是服务器仍然忙于处理原始 AJAX 请求,直到 AJAX 请求处理完成后才返回。

谢谢!

I occasionally have some long running AJAX requests in my Wicket application. When this occurs the application is largely unusable as subsequent AJAX requests are queued up to process synchronously after the current request. I would like the request to terminate after a period of time regardless of whether or not a response has been returned (I have a user requirement that if this occurs we should present the user an error message and continue). This presents two questions:

  1. Is there any way to specify a
    timeout that's specific to an AJAX
    or all AJAX request(s)?
  2. If not, is there any way to kill the current request?

I've looked through the wicket-ajax.js file and I don't see any mention of a request timeout whatsoever.

I've even gone so far as to try re-loading the page after some timeout on the client side, but unfortunately the server is still busy processing the original AJAX request and does not return until the AJAX request has finished processing.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹿港小镇 2024-08-31 02:09:32

我认为让客户“取消”请求不会对您有帮助。 (但是这可能有效。)

关键是服务器正忙于处理不再需要的请求。如果您想使此类操作超时,您必须在服务器端实现超时。如果操作花费的时间太长,服务器将中止该操作并返回一些错误值作为 Ajax 请求的结果。

关于您的排队问题:尽管有同步请求,您也可以考虑使用异步请求。这意味着客户端首先发送启动长时间运行进程的请求。该请求立即返回。然后客户端定期轮询服务器并询问该过程是否已完成。这些轮询请求也会立即返回,表明该进程仍在运行或已完成并取得了特定结果。

I think it won't help you to let the client 'cancel' the request. (However this could work.)

The point is that the server is busy processing a request that is not required anymore. If you want to timeout such operations you had to implement the timeout on the server side. If the operation takes too long, then the server aborts it and returns some error value as the result of the Ajax request.

Regarding your queuing problem: You may consider to use asynchronous requests in spite of synchronous ones. This means that the client first sends a request for starting the long running process. This request immediately returns. Then the client periodically polls the server and asks if the process has finished. Those poll requests also return immediately saying either that the process is still running or that it has finished with a certain result.

别理我 2024-08-31 02:09:32

失败的解决方案:在给定的 setTimeout 之后,我终止活动传输并重新启动通道,该通道处理客户端的所有内容。我通过将每个请求绑定到一个 ID 并对照全局引用进行检查来避免请求冲突,该全局引用在每次发出请求和每次请求完成时都会递增。

 function longRunningCallCheck(refId) {
    // make sure the reference id matches the global id.
    // this indicates that we are still processing the
    // long running ajax call.
    if(refId == id){
        // perform client processing here

        // kill all active transport layers
        var t = Wicket.Ajax.transports;
        for (var i = 0; i < t.length; ++i) {
            if (t[i].readyState != 0) {
                t[i].onreadystatechange = Wicket.emptyFunction;
                t[i].abort();
            }
        }

        // process the default channel
        Wicket.channelManager.done('0|s');
    }
 }

不幸的是,这仍然使 PageMap 被阻塞,并且任何后续调用都会等待请求在服务器端完成。

此时我的解决方案是为用户提供使用 BookmarkablePageLink 注销的选项(它实例化一个新页面,因此不会在 PageMap 上发生争用)。绝对不是最佳的。

任何更好的解决方案都非常受欢迎,但这是我能想到的最好的解决方案。

Failed solution: After a given setTimeout I kill the active transports and restart the channel, which handles everything on the client side. I avoided request conflicts by tying each to an ID and checking that against a global reference that increments each time a request is made and each time a request completes.

 function longRunningCallCheck(refId) {
    // make sure the reference id matches the global id.
    // this indicates that we are still processing the
    // long running ajax call.
    if(refId == id){
        // perform client processing here

        // kill all active transport layers
        var t = Wicket.Ajax.transports;
        for (var i = 0; i < t.length; ++i) {
            if (t[i].readyState != 0) {
                t[i].onreadystatechange = Wicket.emptyFunction;
                t[i].abort();
            }
        }

        // process the default channel
        Wicket.channelManager.done('0|s');
    }
 }

Unfortunately, this still left the PageMap blocked and any subsequent calls wait for the request to complete on the server side.

My solution at this point is to instead provide the user an option to logout using a BookmarkablePageLink (which instantiates a new page, thus not having contention on the PageMap). Definitely not optimal.

Any better solutions are more than welcome, but this is the best one I could come up with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文