我正在寻找一些实际将数据推送到客户端的api。现在我正在使用长时间轮询的氛围来实现这一目标。我正在使用启用了彗星的Glassfish 3.1.2。
后来我听说过Servlet 3.0的异步功能。然后我试着想一下我是否可以用它来取代气氛。
这个想法是让一个Servlet在收到请求后将它们放在一个应用程序范围内的List中。然后在一段无限期后我收到另一个请求,然后迭代列表并向客户发送响应。
我编写了第一个接收请求的Servlet,并将AsyncContext放入应用程序范围的列表中。然后我检查了是否正在创建AsyncContext。我写了一个ajax调用,它实际上击中了url。 ajax请求在30秒后超时/死亡。然后我尝试设置AsyncContext的超时并将其设置为负值,以便永远不会发生超时。后来我才知道AsyncContext上的setTimeOut(int)用于不同的目的。现在我无法将时间设置得非常大,因为我不知道发送响应需要多少小时或几天。
然后我想把请求超时设置为某些无限期。但我不知道该怎么做。
使用resource.suspend()可以在大气层中实现同样的效果,它可以无限期地暂停请求。
如果我不能为此使用Servlet 3.0的异步功能那么它的目的是什么?
我对此功能的理解是,如果请求正在等待某个资源说jdbc连接,那么请求将被放入队列中,并且该线程将返回到线程池,以便该线程可用于提供其他要求。 This link实际上启动了异步进程并将对象传递给Runnable并退出doGet方法。如果由于等待某些资源而Runnable需要时间来处理请求,那么该线程将被放回线程池中并被回收。我的理解是否正确?如果我的理解是正确的,那么如果请求超过等待资源的最长时间,它将超时并且将向客户端发送一些异常。如何以编程方式将超时设置为无限期,并在没有大气的情况下实现服务器端推送。
许多文档都说异步servlet可用于将数据推送到客户端。在所有客户端都使用长轮询的情况下,如果服务器不支持异步,则应为每个请求分配一个线程,这将耗尽所有线程并占用大量内存。如果支持异步,则所有请求都将排队,并且线程可以自由地为其他请求提供服务。链接here解释相同。但是在我们收到事件而不是超时之前,我没有看到任何暂停请求的技术。像大气这样的框架如何设法暂停请求?我认为如果http请求可以在servlet 3.0中暂停,那么我们不需要像atmospehre那样的任何框架。即使长轮询也应该没有Web套接字,因为线程不会始终根据servlet 3.0异步功能附加到请求。
答案 0 :(得分:0)
我得到了答案。在调试了大气的suspend()方法之后,我才知道suspend()方法不会无限期地暂停http请求。它会暂停http请求,直到会话超时到期,因为会话中没有意义已过期且请求仍然排队。
现在我要做的是替换氛围框架并使用servlet 3.0的异步功能。
客户端将发送请求。在我的servlet中,我将启动asyncStart(req,res),然后将其超时设置为会话超时。同时如果发生事件,在Runnable中我将提交响应。然后客户端会再发一次请求。
这是我的示例代码
AsyncContext actxt = request.startAsync(request, response);
actxt.setTimeout(request.getMaxInactiveInterval());
executor.execute(new MyService(actxt));
然后我将使用Observer模式创建自己的事件总线。 MyService类将实现一个事件处理程序。稍后该事件将被触发,MySevice的所有实例都将收到此事件,并将提交响应。
如果我的方法是对的,或者我可以改进这种方法,请告诉我。