`
wutao8818
  • 浏览: 616462 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

learn netty 1

    博客分类:
  • io
阅读更多
实现server遇阻。回头学习一下netty自带的一个http server实现。


A ChannelEvent is handled by a list of ChannelHandlers in a ChannelPipeline.The pipeline
implements an advanced form of the Intercepting Filter pattern to give a user full control over how an event
is handled and how the handlers in the pipeline interact with each other.

整体结构见图。




public class MyReadHandler implements SimpleChannelHandler {
public void messageReceived(ChannelHandlerContext ctx, MessageEvent evt) {
Object message = evt.getMessage();
// Do something with the received message.
...
// And forward the event to the next handler.
ctx.sendUpstream(evt);
}
}






/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.netty.example.http;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

/**
 * @author The Netty Project (netty-dev@lists.jboss.org)
 * @author Andy Taylor (andy.taylor@jboss.org)
 */
public class HttpServer {
    public static void main(String[] args) {
        // Configure the server.
        ChannelFactory factory =
              new NioServerSocketChannelFactory(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());

        ServerBootstrap bootstrap = new ServerBootstrap(factory);
       //[color=red]设置管道[/color]
        bootstrap.setPipelineFactory(new HttpServerPipelineFactory());

        bootstrap.setOption("child.tcpNoDelay", true);
        bootstrap.setOption("child.keepAlive", true);

        // Bind and start to accept incoming connections.
        bootstrap.bind(new InetSocketAddress(8080));
    }
}





管道实现类


/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.netty.example.http;

import static org.jboss.netty.channel.Channels.*;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;

/**
 * @author The Netty Project (netty-dev@lists.jboss.org)
 * @author Andy Taylor (andy.taylor@jboss.org)
 */
public class HttpServerPipelineFactory implements ChannelPipelineFactory {
    public ChannelPipeline getPipeline() throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline pipeline = pipeline();

        // Uncomment the following line if you want HTTPS
        //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
        //engine.setUseClientMode(false);
        //pipeline.addLast("ssl", new SslHandler(engine));

        pipeline.addLast("decoder", new HttpRequestDecoder());
        // Uncomment the following line if you don't want to handle HttpChunks.
        //pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
        pipeline.addLast("encoder", new HttpResponseEncoder());

        //[color=red]加入自定义handler[/color]
        pipeline.addLast("handler", new HttpRequestHandler());
        return pipeline;
    }
}





自定义handler类

/*
 * JBoss, Home of Professional Open Source
 * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.netty.example.http;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.Cookie;
import org.jboss.netty.handler.codec.http.CookieDecoder;
import org.jboss.netty.handler.codec.http.CookieEncoder;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpChunk;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;

/**
 * @author The Netty Project (netty-dev@lists.jboss.org)
 * @author Andy Taylor (andy.taylor@jboss.org)
 */
@ChannelPipelineCoverage("one")
public class HttpRequestHandler extends SimpleChannelUpstreamHandler {

    private volatile HttpRequest request;
    private volatile boolean readingChunks;
    private final StringBuilder responseContent = new StringBuilder();

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        if (!readingChunks) {
            HttpRequest request = this.request = (HttpRequest) e.getMessage();
            responseContent.append("WELCOME TO THE WILD WILD WEB SERVER\r\n");
            responseContent.append("===================================\r\n");

            responseContent.append("VERSION: " + request.getProtocolVersion().getText() + "\r\n");

            if (request.containsHeader(HttpHeaders.Names.HOST)) {
                responseContent.append("HOSTNAME: " + request.getHeader(HttpHeaders.Names.HOST) + "\r\n");
            }

            responseContent.append("REQUEST_URI: " + request.getUri() + "\r\n\r\n");

            if (!request.getHeaderNames().isEmpty()) {
                for (String name: request.getHeaderNames()) {
                    for (String value: request.getHeaders(name)) {
                        responseContent.append("HEADER: " + name + " = " + value + "\r\n");
                    }
                }
                responseContent.append("\r\n");
            }

            QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());
            Map<String, List<String>> params = queryStringDecoder.getParameters();
            if (!params.isEmpty()) {
                for (Entry<String, List<String>> p: params.entrySet()) {
                    String key = p.getKey();
                    List<String> vals = p.getValue();
                    for (String val : vals) {
                        responseContent.append("PARAM: " + key + " = " + val + "\r\n");
                    }
                }
                responseContent.append("\r\n");
            }

            if (request.isChunked()) {
                readingChunks = true;
            } else {
                ChannelBuffer content = request.getContent();
                if (content.readable()) {
                    responseContent.append("CONTENT: " + content.toString("UTF-8") + "\r\n");
                }
                writeResponse(e);
            }
        } else {
            HttpChunk chunk = (HttpChunk) e.getMessage();
            if (chunk.isLast()) {
                readingChunks = false;
                responseContent.append("END OF CONTENT\r\n");
                writeResponse(e);
            } else {
                responseContent.append("CHUNK: " + chunk.getContent().toString("UTF-8") + "\r\n");
            }
        }
    }

    private void writeResponse(MessageEvent e) {
        // Convert the response content to a ChannelBuffer.
        ChannelBuffer buf = ChannelBuffers.copiedBuffer(responseContent.toString(), "UTF-8");
        responseContent.setLength(0);

        // Decide whether to close the connection or not.
        boolean close =
            HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION)) ||
            request.getProtocolVersion().equals(HttpVersion.HTTP_1_0) &&
            !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.getHeader(HttpHeaders.Names.CONNECTION));

        // Build the response object.
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.setContent(buf);
        response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
        response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(buf.readableBytes()));

        String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
        if (cookieString != null) {
            CookieDecoder cookieDecoder = new CookieDecoder();
            Set<Cookie> cookies = cookieDecoder.decode(cookieString);
            if(!cookies.isEmpty()) {
                // Reset the cookies if necessary.
                CookieEncoder cookieEncoder = new CookieEncoder(true);
                for (Cookie cookie : cookies) {
                    cookieEncoder.addCookie(cookie);
                }
                response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
            }
        }

        // Write the response.
        ChannelFuture future = e.getChannel().write(response);

        // Close the connection after the write operation is done if necessary.
        if (close) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {
        e.getCause().printStackTrace();
        e.getChannel().close();
    }
}




需要进一步了解

杭州社区购物-滨江区西兴街道连园商铺李宁全场大优惠
  • 大小: 20.5 KB
分享到:
评论
1 楼 laser_lu 2010-03-06  
Netty是很不错的,据说plurk.com在用它做http comet应用,单机可以达到10万并发连接。

相关推荐

    netty_learn_netty_

    标题中的"Netty_Learn_Netty_"暗示了这是一个关于学习Netty框架的资源集合,而描述中的"some code for learn netty and do"表明其中可能包含了一些代码示例,用于帮助理解和实践Netty的用法。标签"Netty"进一步确认...

    netty_learn_netty_源码.zip

    1. **NIO (非阻塞I/O)**: Netty基于Java NIO(非阻塞I/O)构建,允许在一个线程中处理多个连接,提高了系统资源利用率,特别适合高并发场景。 2. **EventLoop(事件循环)**: Netty的EventLoop是处理I/O事件的核心...

    netty入门与实战-netty-learn.zip

    1. **NIO(Non-blocking I/O)**:Netty 基于 Java NIO(非阻塞I/O)构建,它允许单个线程处理多个连接,从而提高了服务器的并发处理能力。 2. **Channel**:在 Netty 中,Channel 是网络连接的抽象,它代表了从一...

    Netty学习与实战Demo-netty-learn.zip

    1. **Netty核心概念** - **NIO(非阻塞I/O)**: Netty基于Java NIO(New I/O)库构建,它允许在单个线程中处理多个连接,减少了线程创建和上下文切换的开销。 - **Channel**: 在Netty中,Channel代表一个到另一端...

    learn_netty_source_code:Netty源码分析教程

    在工作中,虽然我经常使用到Netty库,但是很多时候对Netty的一些概念还是位于知其然,不知其所以然的状态,因此就萌生了学习Netty源码的想法。刚开始看原始代码的时候,自然是比较痛苦的,首先有两个:第一,网上...

    netty-learn:Netty4.X社区配套原始码,博客地址:https

    Netty 4.x写一个分区服务器 写个特定服务器 世上最简单的协议不是而是DISCARD(替代)。这个协议将会丢掉任何收到的数据,而不响应。 为了实现DISCARD协议,您只需忽略所有收到的数据。让我们从handler(处理器)的...

    learn-netty-in-aciton:《 Netty实战(Netty IN ACTION)》源码仓库

    通过深入学习和实践`learn-netty-in-action-master`中的内容,你不仅可以了解Netty的内部机制,还能掌握如何利用Netty构建高效、稳定的网络服务。此外,由于Netty是一个开源项目,你还可以参与到社区中,与其他...

    Netty In Action

    Netty is a Java-based networking framework designed to handle asynchronous network events smoothly so your applications are easy to write and maintain. The framework hides all the boilerplate and low...

    nettylearn2_netty_

    描述中提到的"some code for learn netty or project"表明这个压缩包可能包含了一些代码示例或者一个实际的Netty项目,用于学习和实践Netty的使用。学习Netty通常涉及理解其核心概念,如NIO(非阻塞I/O)、Channel、...

    Netty-learn:netty学习记录

    1. **异步事件驱动**:Netty基于Java NIO(非阻塞I/O)构建,利用了回调函数和事件循环模型,提高了系统的并发能力。这使得Netty能够高效地处理大量并发连接,特别适合于长连接和高负载的网络服务。 2. **高性能**...

    读书笔记:Netty权威指南第二版Learn.zip

    读书笔记:Netty权威指南第二版Learn

    netty博文资料

    博文中的“learn_channel”可能是指学习 Netty 中 Channel 相关的知识点。这包括但不限于理解 Channel 的状态(如 OPEN、CONNECTED、BOUND、ACTIVE 等)、如何注册 Channel 到 EventLoop、如何处理 I/O 事件、以及...

    Netty in Action(Manning,2015)

    You'll learn to write highly scalable applications without the need to dive into the low-level non-blocking APIs at the core of Java. Purchase of the print book includes a free eBook in PDF, Kindle,...

    netty4.0.27learn2:学习netty源码,而建造的一个eclipse project项目

    该项目是为了学习netty4.0的源码而创建的。 净额项目 Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。 链接 如何建造 有关构建和开发Netty的详细信息,请访问。 该页面...

    netty-jike-learn:极客时间netty原始码课程注释代码

    净额项目Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。链接如何建造有关构建和开发Netty的详细信息,请访问。 该页面仅提供非常基本的信息。 您需要以下内容来构建...

    Netty in Action

    Netty is a Java-based networking framework designed to handle asynchronous network events smoothly so your applications are easy to write and maintain. The framework hides all the boilerplate and low...

    learn-netty:Netty原始解析(原始码和笔记)

    Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。 链接 如何建造 有关构建和开发Netty的详细信息,请访问。 该页面仅提供非常基本的信息。 您需要以下内容来构建Netty...

Global site tag (gtag.js) - Google Analytics