在Web应用程序中实现长时间运行的进程

时间:2013-08-01 21:05:03

标签: java jquery spring

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

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

4 个答案:

答案 0 :(得分:1)

我最近必须解决这样的问题而且非常简单。他就是我这么说的原因。

  1. 使用HTTP 1.1协议,服务器连接将保持打开状态,直到返回请求的最后一个资源。任何符合HTTP 1.1标准的Web服务器都可以为您完成此任务,而无需您付出任何努力。仅这一点就可以解决您的问题,更容易解决

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

  3. 对于客户端来说,这个异步过程看起来像服务器正在永远响应,因此客户端会耐心地等待响应。你需要做一些与众不同的事情。

  4. 在客户端,任何调用ajax请求的方法都已足够。不需要轮询。客户很乐意坐下来等待回复。 xmlHttpRequest对象的'readyState'属性将为您处理此问题。一旦服务器提交了响应,'readyState'值将更改为4,然后您可以更新UI。

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

    无论如何,我希望我能帮助你,同时也为你提供了如何向前发展的线索。

答案 1 :(得分: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);
  }
}

答案 2 :(得分:0)

我会考虑推送通知SaaS,例如http://pusher.com/

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

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");

答案 3 :(得分:0)

我认为最佳解决方案如下。有一个DB表来监视后端任务。前端会定期通过后端服务查询该表以获取状态。状态完成后,它会通知用户。