文档章节

Jetty源码-Continuation

robin-yao
 robin-yao
发布于 2015/04/26 21:07
字数 765
阅读 36
收藏 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
粉丝 151
博文 54
码字总数 61496
作品 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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JS:异步 - 面试惨案

为什么会写这篇文章,很明显不符合我的性格的东西,原因是前段时间参与了一个面试,对于很多程序员来说,面试时候多么的鸦雀无声,事后心里就有多么的千军万马。去掉最开始毕业干了一年的Jav...

xmqywx
今天
0
0
Win10 64位系统,PHP 扩展 curl插件

执行:1. 拷贝php安装目录下,libeay32.dll、ssleay32.dll 、 libssh2.dll 到 C:\windows\system32 目录。2. 拷贝php/ext目录下, php_curl.dll 到 C:\windows\system32 目录; 3. p...

放飞E梦想O
今天
0
0
谈谈神秘的ES6——(五)解构赋值【对象篇】

上一节课我们了解了有关数组的解构赋值相关内容,这节课,我们接着,来讲讲对象的解构赋值。 解构不仅可以用于数组,还可以用于对象。 let { foo, bar } = { foo: "aaa", bar: "bbb" };fo...

JandenMa
今天
1
0
OSChina 周一乱弹 —— 有人要给本汪介绍妹子啦

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享水木年华的单曲《中学时代》@小小编辑 手机党少年们想听歌,请使劲儿戳(这里) @须臾时光:夏天还在做最后的挣扎,但是晚上...

小小编辑
今天
21
5
centos7安装redis及开机启动

配置编译环境: sudo yum install gcc-c++ 下载源码: wget http://download.redis.io/releases/redis-3.2.8.tar.gz 解压源码: tar -zxvf redis-3.2.8.tar.gz 进入到解压目录: cd redis-3......

hotsmile
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部