以异步方式实现长轮询 [英] Implementing long polling in an asynchronous fashion
问题描述
是否可以从其线程中取出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屋!