1

我正在寻找一些实际上将数据推送到客户端的 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 连接,那么该请求将被放置在一个队列中,并且该线程将返回到线程池,以便该线程可以为其他请求提供服务. 此链接实际上启动了一个异步进程并将对象传递给 Runnable 并退出 doGet 方法。如果 Runnable 由于等待某些资源而需要时间来处理请求,则线程将被放回线程池并回收。我的理解正确吗?如果我的理解是正确的,那么如果请求超过等待资源的最长时间,它将超时并且会向客户端发送一些异常。如何以编程方式将超时设置为无限期并实现无气氛的服务器端推送。

许多文档说可以使用异步 servlet 将数据推送到客户端。在所有客户端都使用长轮询的情况下,如果服务器不支持异步,则应为每个请求分配一个线程,这将耗尽所有线程并使用大量内存。如果支持异步,所有请求都将被排队,线程将可以自由地处理其他请求。这里的链接解释相同。但是在我们收到事件而不是超时之前,我看不到任何暂停请求的技术。像气氛这样的框架如何设法暂停请求?我认为如果可以在 servlet 3.0 中暂停 http 请求,那么我们不需要像 atmospehre 这样的框架。即使是长轮询也应该可以代替 Web 套接字,因为根据 servlet 3.0 异步特性,线程不会始终附加到请求上。

4

1 回答 1

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

然后我将使用观察者模式创建自己的事件总线。MyService 类将实现一个事件处理程序。稍后该事件将被触发,并且 MyService 的所有实例都将收到此事件并提交响应。

请让我知道我的方法是否正确,或者该方法是否可以改进。

于 2013-09-03T12:44:54.913 回答