以异步方式实现长轮询 [英] Implementing long polling in an asynchronous fashion

查看:442
本文介绍了以异步方式实现长轮询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以从其线程中取出HTTPServletRequest,解散此线程(即将其带回池中),但保持与浏览器的基础连接正常工作,直到我从耗时的操作中获得结果(说,处理图像)?处理返回数据时,应该异步调用另一个方法,并将请求和数据作为参数给出。

Is it possible to take an HTTPServletRequest away from its thread, dissolve this thread (i.e. bring it back to the pool), but keep the underlying connection with the browser working, until I get the results from a time-consuming operation (say, processing an image)? When the return data are processed, another method should be called asynchronously, and be given the request as well as the data as parameters.

通常,长池函数在一个漂亮的阻止时尚,当前线程没有被解散,这在并发连接方面降低了服务器端应用程序的可伸缩性。

Usually, long pooling functions in a pretty blocking fashion, where the current thread is not dissolved, which reduces the scalability of the server-side app, in terms of concurrent connections.

推荐答案

是的,您可以使用Servlet 3.0执行此操作

Yes, you can do this with Servlet 3.0

以下是每30秒写一次警报的示例(未测试)。

Below is the sample to write the alert every 30 secs(not tested).

@WebServlet(async ="true")
public class AsyncServlet extends HttpServlet {

Timer timer = new Timer("ClientNotifier");

public void doGet(HttpServletRequest req, HttpServletResponse res) {

    AsyncContext aCtx = request.startAsync(req, res);
    // Suspend request for 30 Secs
    timer.schedule(new TimerTask(aCtx) {

        public void run() {
            try{
                  //read unread alerts count
                 int unreadAlertCount = alertManager.getUnreadAlerts(username); 
                  // write unread alerts count
    response.write(unreadAlertCount); 
             }
             catch(Exception e){
                 aCtx.complete();
             }
        }
    }, 30000);
}
}

以下是根据事件编写的示例。必须实现alertManager,当客户端必须被警告时通知AlertNotificationHandler。

Below is the sample to write based on an event. The alertManager has to be implemented which notifies AlertNotificationHandler when client has to be alerted.

@WebServlet(async="true")
public class AsyncServlet extends HttpServlet {
 public void doGet(HttpServletRequest req, HttpServletResponse res) {
        final AsyncContext asyncCtx = request.startAsync(req, res);
        alertManager.register(new AlertNotificationHandler() {
                   public void onNewAlert() { // Notified on new alerts
                         try {
                               int unreadAlertCount =
                                      alertManager.getUnreadAlerts();
                               ServletResponse response = asyncCtx.getResponse();
                               writeResponse(response, unreadAlertCount);
                               // Write unread alerts count
                         } catch (Exception ex) {
                               asyncCtx.complete();
                               // Closes the response
                         }
                   }
        });
  }
}

这篇关于以异步方式实现长轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆