我是spring的新手,想对网站实施长轮询,以便在所有客户都可以使用时立即显示管理消息,我在google上搜索了几个小时,只能发现deferredresult(spring 3.2)可以用来实现它。我的问题是我如何使用 deferredresult 实现长轮询,如果有人可以向我推荐这样的教程,我将不胜感激。
3 回答
另一种选择是使用 AsyncContext。这将使初始 GET 请求保持“打开”状态,并使您能够发送多条消息作为响应的一部分,这与 DeferredResult 不同,它只允许发送一条响应消息。这是一个很好的链接,解释了如何!
直出马口。
您有两个基本选项:选项 1 是 Callable ,其中 Callable 返回 String 视图名称(您也可以使用 @ResponseBody 或其他一些正常的 Spring 返回类型,如 ModelAndView,但我从未调查过)。
选项二是返回DeferredResult,类似于Callable。除非您可以将其传递给单独的线程并在那里填写结果。同样,不确定您是否可以返回 ModelAndView 或使用 @ResponseBody 返回 XML/JSON,但我相信您可以。
关于背景的简短介绍DeferredResult
:您的控制器最终是由 servlet 容器(就此而言,假设服务器容器是 Tomcat)工作线程执行的函数。您的服务流程以 Tomcat 开始,以 Tomcat 结束。Tomcat从客户端获取请求,持有连接,最终返回响应给客户端。您的代码(控制器或 servlet)位于中间的某个位置。
考虑这个流程:
- Tomcat 获取客户端请求。
- Tomcat 执行你的控制器。
- 释放 Tomcat 线程但保持客户端连接(不返回响应)并在不同线程上运行繁重的处理。
- 当您的繁重处理完成后,使用其响应更新 Tomcat 并将其返回给客户端(通过 Tomcat)。
因为 servlet(你的代码)和 servlet 容器(Tomcat)是不同的实体,所以为了允许这个流程(释放 tomcat 线程但保持客户端连接),我们需要在他们的合同中提供这种支持,包,在Servletjavax.servlet
中引入3.0 . 当控制器的返回值为DeferredResult
or时,Spring MVC 使用这个新的 Servlet 3.0 功能Callable
,尽管它们是两个不同的东西。Callable
是一个接口,它是 的一部分java.util
,它是对Runnable
接口的改进。DeferredResult
是一个类由 Spring 设计,允许更多选项(我将描述)用于 Spring MVC 中的异步请求处理,并且此类仅保存结果(如其名称所暗示的那样),而您的Callable
实现保存异步代码。所以这意味着你可以在你的控制器中使用这两者,运行你的异步代码Callable
并将结果设置在 中DeferredResult
,这将是控制器的返回值。那么通过使用DeferredResult
作为返回值而不是 Callable 会得到什么?DeferredResult
具有内置回调,如onError
,onTimeout
和onCompletion
. 它使错误处理变得非常容易。此外,由于它只是结果容器,您可以选择任何线程(或线程池)在您的异步代码上运行。使用 Callable,您没有这个选择。
在这里,您可以找到我使用两个选项创建的简单工作示例,Callable
并且DeferredResult
.