1

出于某种原因,我在谷歌上找不到解决方案。我可以在 Web 应用程序中选择上传大量数据(在文件中)并通过后端处理(我们使用 Java/Spring)来存储这些数据。大概需要5分钟。是否有人知道用户可以启动此过程并执行其他操作以及何时完成通知用户的方式?

我正在考虑的一个解决方案(不确定是否有更好的一次,这就是我在这里的原因)是进行 AJAX 调用(我们碰巧使用了 jQuery 库),它将文件传递给控制器​​,然后控制器将处理文件,它会定期向流发送一些小东西,这样就不会发生超时,然后一旦完成,它将通知它将通知用户的 Web 应用程序。

4

4 回答 4

1

我最近不得不解决这样的问题,这真的很容易。他就是我这么说的原因。

  1. 使用 HTTP 1.1 协议,服务器连接保持打开状态,直到返回请求的最后一个资源。任何符合 HTTP 1.1 的网络服务器都会在后台为您完成此操作,而无需您付出任何努力。仅此一项就使您的问题更容易解决

  2. 使用 servlet 3.0,您应该利用新的异步功能(尽管您可以在 servlet < 3.0 中自行推出类似的功能)。服务器为来自其线程池的每个传入请求分配一个新线程。然后使用您自己的自定义线程池,将此请求线程的处理与 asyncContext 一起移交给自定义线程。你自己的线程会处理这个长时间运行的进程,服务器的线程会立即返回处理其他请求。asyncContext 包含原始请求/响应对象,但它们处于“冻结”状态。当您的长时间运行的进程完成时,它将调用 asyncContext.complete() 方法。此操作将提交处于“冻结”状态的原始请求/响应。

  3. 对客户端来说,这个异步过程看起来服务器需要永远响应,因此客户端会耐心地等待响应。你不需要做任何不寻常的事情。

  4. 在客户端,任何调用 ajax 请求的方法都足够了。不需要轮询。客户会很高兴地坐下来等待响应。xmlHttpRequest 对象的'readyState' 属性将为您解决这个问题。服务器提交响应后,“readyState”值将更改为 4,您可以从那里更新您的 UI。

在服务器端,您可能应该将具有长期运行进程方法的类包装在一个内部类中,然后该内部类将调用长期运行进程并保存一个布尔属性,例如“running = true/false”。这样,如果在您长时间运行的请求中,有人尝试再次调用相同的进程,他们将能够知道它是否已经在运行。现在,这比您要求的要详细。

无论如何,我希望我能提供帮助,同时为您提供有关如何前进的线索。

于 2013-11-25T00:37:17.920 回答
0

我会考虑像http://pusher.com/这样的推送通知 SaaS

客户端向服务器发送请求需要一段时间:

POST /process-file

服务器响应

HTTP 202 Accepted

{ channelName:'some-channel', events:[{name:'my-processing-complete-event'}] }

在客户端,在 JavaScript 中,订阅频道并收听:

var channel = pusher.subscribe('some-channel');
channel.bind('my-processing-complete-event', function(message){
  alert(message);
});

在服务器上,当处理完成时,您通知您的推送服务,然后通知所有客户端。

pusher.trigger("some-channel", "my-processing-complete-event", "processing done");
于 2013-08-01T23:13:00.873 回答
0

我认为最好的解决方案如下。有一个监控后端任务的数据库表。前端通过后端服务定期查询该表的状态。一旦状态完成,它就会通知用户。

于 2013-08-02T14:18:34.290 回答
0

我们可以为此使用jquery ajax吗

success: function(xhr_data) {
  console.log(xhr_data);
  if (xhr_data.status == 'pending') {

    if (cnt < 6) {
        cnt++;
        setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
    }

  } else {
    success(xhr_data);
  }
}
于 2013-08-01T21:32:04.800 回答