文档章节

Jetty源码-Continuation

robin-yao
 robin-yao
发布于 2015/04/26 21:07
字数 765
阅读 37
收藏 1

    本文主要介绍Jetty 异步的请求。Jetty Contination可以用来处理大量的时间比较长的连接请求。

    http异步请求在Servlet3中已经实现,使用十分方便,通过Request获取异步AsyncContext,然后在上面注册自己的异步监听器AsynListener即可。Tomcat7 和Jetty8以上版本等主流的容器都支持Servlet3的异步请求。具体介绍见http://www.importnew.com/8864.html,详细的Demohttps://github.com/WangErXiao/Servlet3-Async。这里不多介绍Servlet3的异步请求。

    Jetty的异步请求的实现模块主要是Continuation。通过continuation机制,HTTP 请求可以被挂起,超时或者异步事件发生后重新开始。Continuation接口包含两个重要的方法是suspend()和resume()。

    当调用continuation.suspend()方法时,会把当前servlet的request和相关的response挂起,request的生命周期将被从Servlet.service(ServletRequest, ServletResponse)扩展到容器,response将不会被提交除非有ContinuationThrowable抛出。调用完suspend方法,注册完异步的handler,直接调用return从Servlet.service方法返回,当前的线程就可以去处理其他任务了。

    任务处理完之后,通过注册好的回调方法调用continuation.resume()。重新用原来的request和reponse发起请求,并从request中获取结果,通过response返回。

    下边是具体的Demo代码:

public class SimpleSuspendResumeServlet extends HttpServlet {
    private MyAsyncHandler myAsyncHandler;
    //初始化异步处理器
    public void init() throws ServletException {
        myAsyncHandler = new MyAsyncHandler() {
            public void register(final MyHandler myHandler) {
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep(10000);
                            //设置结果,调用resume方法
                            myHandler.onMyEvent("complete!");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }).start();
            }
        };

    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        final PrintWriter writer = response.getWriter();
        final Continuation continuation = ContinuationSupport
                .getContinuation(request);
        if (continuation.isInitial()) {
            sendMyFirstResponse(response);
            continuation.suspend(); // always suspend before registration
            myAsyncHandler.register(new MyHandler() {
                public void onMyEvent(Object result) {
                    continuation.setAttribute("results", result);
                    continuation.resume();
                }
            });
            return; // 然后该线程就可以去处理其他任务了
        }

        if (continuation.isExpired()) {
            sendMyTimeoutResponse(response);
            return;
        }
        //Send the results
        Object results = request.getAttribute("results");
        if(results==null){
            response.getWriter().write("why reach here??");
            continuation.resume();
            return;
        }
        sendMyResultResponse(response, results);
    }

    private interface MyAsyncHandler {
        public void register(MyHandler myHandler);
    }

    private interface MyHandler {
        public void onMyEvent(Object result);
    }

    private void sendMyFirstResponse(HttpServletResponse response) throws IOException {
        response.setContentType("text/html");
        response.getWriter().write("start---------");
        response.getWriter().flush();
    }

    private void sendMyResultResponse(HttpServletResponse response,
                                      Object results) throws IOException {
        response.getWriter().write("results:" + results);
        response.getWriter().flush();

    }
    private void sendMyTimeoutResponse(HttpServletResponse response)
            throws IOException {
        response.getWriter().write("timeout");
    }
}

    上面代码中的Support,是工厂类,用来生成Continuation。如果当前容器采用的是Servlet3,返回Servlet3Continuation类型的,如果不是返回FauxContinuation类型的。Servlet3Continuation顾名思义是借助Servlet3里的异步机制来实现的,底层的具体实现还是由具体的容器实现,tomcat7,jetty8以上版本都实现Servlet3异步请求功能。FauxContinuation是Continuation阻塞实现方式,主要是针对才非Servlet3的容器,通过ContinuationFilter过滤器,把FauxContinuation添加到request属性中:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    if (_filtered)
    {
        Continuation c = (Continuation) request.getAttribute(Continuation.ATTRIBUTE);
        FilteredContinuation fc;
        if (_faux && (c==null || !(c instanceof FauxContinuation)))
        {
            fc = new FauxContinuation(request);
            request.setAttribute(Continuation.ATTRIBUTE,fc);
        }
        else
            fc=(FilteredContinuation)c;

        boolean complete=false;
        while (!complete)
        {
            try
            {
                if (fc==null || (fc).enter(response))
                    chain.doFilter(request,response);
            }
            catch (ContinuationThrowable e)
            {
                debug("faux",e);
            }
            finally
            {
                if (fc==null)
                    fc = (FilteredContinuation) request.getAttribute(Continuation.ATTRIBUTE);

                complete=fc==null || (fc).exit();
            }
        }
    }
    else
    {
        try
        {
            chain.doFilter(request,response);
        }
        catch (ContinuationThrowable e)
        {
            debug("caught",e);
        }
    }
}

END-------------------------------

转发请标注来源http://my.oschina.net/robinyao/blog/406544

© 著作权归作者所有

共有 人打赏支持
robin-yao
粉丝 155
博文 53
码字总数 60598
作品 0
杭州
Jetty7 Continuation 学习

Jetty Continuation 实际上是一种异步Http技术,他能让Http连接挂起,直到超时或者异步事件发生时,Http连接可以恢复。Jetty Continuation 的技术应用起来不复杂,有几个关键的API,和两种设...

爱coding
2012/06/01
0
1
有人在实际生产环境下使用jetty吗?

现在想用jetty的Continuation功能实现系统的一个即时通信功能。 不知道jetty的性能和稳定性怎么样。 以前都是用的tomcat,没有在正式环境下用过jetty,请大家用过的给点经验之谈。...

ferly
2010/06/17
3.4K
10
号外号外,Jetty 9 正式版发布!!!

Jetty 9 正式版来了!!!版本标签:Jetty 9.0.0.v20130308 Jetty 9 支持 SPDY 和 WebSocket。 下载地址: http://download.eclipse.org/jetty/stable-9/dist/ Maven: http://search.maven.......

oschina
2013/03/09
15.1K
34
Jetty 9.3.1.v20150714 发布,支持 HTTP/2

Jetty 9.3.1.v20150714 发布,这是 9.3.x 维护版本,支持HTTP/2,更新内容如下: + 441020 Support HEADERS followed by CONTINUATION+. + 460671 Rationalize property names (fix for jet......

oschina
2015/07/17
2.1K
6
OpenFire与其他消息服务器交互

web系统中采用jetty+continuation长连接的方式来处理聊天信息发送,现在要在手机应用中加入即时消息发送的功能,采用这个处理方式基本上不怎么好。于是,就通过openfire来处理消息交互,但是...

溜子冲的根
2013/08/27
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

一个可能的NEO链上安全随机数解决方案

0x00 困境 链上安全随机数生成应该算是一个比较蛋疼的问题,哪怕你的系统再牛逼,合约程序困在小小的虚拟机里,哪怕天大的本事也施展不开。 更悲催的是,交易执行的时候,是在每一个节点都执...

暖冰
今天
1
0
【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
4
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
19
2

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部