我正在使用 Spring MVC 编写一个内部 Web 应用程序,其中用户将提交一组作业以通过 RESTful Web 服务完成。每个作业只需几秒钟即可完成,但用户可以提交数十个作业。我希望在每个作业完成时通知用户的选项。这将部署到 Tomcat 6 安装,这在一定程度上限制了我的选择,因为我将无法访问 Servlet 3。
我以前从来没有写过这样的东西,我也不完全确定该怎么做。我在想我想做某种长轮询,但是,虽然它在概念上看起来很容易,但我不确定如何用 Spring 来实现它。
我最初的计划是简单地保持连接打开(如果用户设置了接收通知的选项),在单独的线程中启动作业,当作业完成时通过 BlockingQueue 向请求线程发送消息并将消息转发到用户。但是,我认为让连接保持打开那么长时间可能不是一个好主意。我也没有看到 jQuery 在完成之前开始处理 AJAX 响应的方法。
另一种选择是长轮询。我看到 Spring 3.2 引入了一个新功能来执行这里描述的操作,但是 1)我不确定这是否依赖于 Servlet 3 中的异步支持,2)我不清楚如何从该示例中使用它(如果有人能指出我更彻底的信息,将不胜感激),以及 3)这可能会出现问题,因为我将使用 Spring Security 来锁定这个应用程序。
所以,我可以实现自己的长轮询机制。有没有关于如何处理这个问题的最佳实践?我在想我可以保留一个单例 ConcurrentMap ,其中会话 id 作为键和 BlockingQueue 中的消息作为值。工作线程会将消息放入适当的 BlockingQueue 中,并且当消息请求进入会话时,它将从阻塞队列中删除,直到发布一些终端消息。但是还有一个问题,如果客户端永远不会回来耗尽消息队列怎么办。怎么会被清理掉?我有一种直觉,认为有更好的方法来实现这一点,但我不确定那是什么。有人可以在这里给我一些指导吗?