Netty 基于Http協議下的數據傳輸示例

jopen 10年前發布 | 134K 次閱讀 Netty 網絡工具包

Http/Https協議是最重要最常用到的協議之一,Netty提供了一些了的Handler來處理Http協議下的編碼工作。下面就介紹一個Netty實例:

1.通過HttpClient發送Protobuf類型數據到服務端

2.服務端Netty負責把接收到的Http請求中的數據再發送到客戶端。

3.其中Netty對發送的數據量沒有限制,因為Http發送的message往往是由一系列infragment構成,Netty可以把接收到的http請求片段信息整合(Aggregator)到一起,最終得到一個FullHttpRequest。

 

Client端:

    package NettyDemo.echo.client;  

    import java.io.IOException;  
    import org.apache.http.HttpEntity;  
    import org.apache.http.HttpHost;  
    import org.apache.http.HttpResponse;  
    import org.apache.http.client.ClientProtocolException;  
    import org.apache.http.client.methods.HttpPost;  
    import org.apache.http.conn.params.ConnRoutePNames;  
    import org.apache.http.entity.ByteArrayEntity;  
    import org.apache.http.impl.client.DefaultHttpClient;  
    import NettyDemo.echo.protocal.AddressBookProtos;  
    import NettyDemo.echo.server.HttpProtobufServer;  

    public class HttpClientDemo {  
        public static void main(String[] args) throws ClientProtocolException,  
                IOException {  
            DefaultHttpClient httpclient = new DefaultHttpClient();  
            HttpHost proxy = new HttpHost(HttpProtobufServer.IP,  
                    HttpProtobufServer.PORT);  
            httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,  
                    proxy);  
            HttpPost httppost = new HttpPost("");  
            AddressBookProtos.AddressBook.Builder address = AddressBookProtos.AddressBook  
                    .newBuilder();  
            for (int i = 0; i < 20000; i++) {  
                AddressBookProtos.Person.Builder person = AddressBookProtos.Person  
                        .newBuilder();  
                person.setName("HeavenWang");  
                person.setId(i);  
                person.setEmail("wanghouda@126.com");  
                address.addPerson(person);  
            }  
            ByteArrayEntity entity = new ByteArrayEntity(address.build().toByteArray());  
            httppost.setEntity(entity);  
            HttpResponse response = httpclient.execute(httppost);  
            HttpEntity receiveEntity = response.getEntity();  
            System.out.println("----------------------------------------");  
            System.out.println(response.getStatusLine());  
            if (receiveEntity != null) {  
                System.out.println("Response content length: " + receiveEntity.getContentLength());  
            }  
            System.out.println("success");  
        }  
    }  

服務器端NettyService:


package NettyDemo.echo.server;  

import io.netty.bootstrap.ServerBootstrap;  
import io.netty.channel.ChannelInitializer;  
import io.netty.channel.ChannelPipeline;  
import io.netty.channel.EventLoopGroup;  
import io.netty.channel.nio.NioEventLoopGroup;  
import io.netty.channel.socket.SocketChannel;  
import io.netty.channel.socket.nio.NioServerSocketChannel;  
import io.netty.handler.codec.http.HttpObjectAggregator;  
import io.netty.handler.codec.http.HttpRequestDecoder;  
import io.netty.handler.codec.http.HttpResponseEncoder;  
import io.netty.handler.codec.http.HttpServerCodec;  
import NettyDemo.echo.handler.HttpProtobufServerHandler;  

public class HttpProtobufServer {  
    public static final String IP = "127.0.0.1";  
    public static final int PORT = 8080;  
    //private static MessageLite lite=AddressBookProtos.AddressBook.getDefaultInstance();  
    /**用于分配處理業務線程的線程組個數 */  
    protected static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2; //默認  
    /** 業務出現線程大小*/  
    protected static final int BIZTHREADSIZE = 4;  
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);  
    private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);  
    protected static void run() throws Exception {  
        ServerBootstrap b = new ServerBootstrap();  
        b.group(bossGroup, workerGroup);  
        b.channel(NioServerSocketChannel.class);  
        b.childHandler(new ChannelInitializer<SocketChannel>() {  
            @Override  
            public void initChannel(SocketChannel ch) throws Exception {  
                ChannelPipeline pipeline = ch.pipeline();                 
                pipeline.addLast("decoder", new HttpRequestDecoder());  
                /**usually we receive http message infragment,if we want full http message, 
                 * we should bundle HttpObjectAggregator and we can get FullHttpRequest。 
                 * 我們通常接收到的是一個http片段,如果要想完整接受一次請求的所有數據,我們需要綁定HttpObjectAggregator,然后我們 
                 * 就可以收到一個FullHttpRequest-是一個完整的請求信息。 
                **/  
                pipeline.addLast("servercodec",new HttpServerCodec());  
                pipeline.addLast("aggegator",new HttpObjectAggregator(1024*1024*64));//定義緩沖數據量  
                pipeline.addLast(new HttpProtobufServerHandler());  
                pipeline.addLast("responseencoder",new HttpResponseEncoder());  
            }  
        });  
        b.bind(IP, PORT).sync();  
        System.out.println("TCP服務器已啟動");  
    }  

    protected static void shutdown() {  
        workerGroup.shutdownGracefully();  
        bossGroup.shutdownGracefully();  
    }  

    public static void main(String[] args) throws Exception {  
        System.out.println("開始啟動http服務器...");  
        HttpProtobufServer.run();  
//      TcpServer.shutdown();  
    }  
}  

Handler:

    package NettyDemo.echo.handler;  

    import io.netty.channel.ChannelHandlerContext;  
    import io.netty.channel.SimpleChannelInboundHandler;  
    import io.netty.handler.codec.http.DefaultFullHttpRequest;  
    import io.netty.handler.codec.http.DefaultFullHttpResponse;  
    import io.netty.handler.codec.http.HttpResponseStatus;  
    import io.netty.handler.codec.http.HttpVersion;  

    public class HttpProtobufServerHandler extends SimpleChannelInboundHandler<Object>{  
        @Override  
        protected void channelRead0(ChannelHandlerContext ctx,  Object msg) throws Exception {  
            DefaultFullHttpRequest request=(DefaultFullHttpRequest)msg;  
            DefaultFullHttpResponse response=new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.ACCEPTED, request.content());  
            ctx.writeAndFlush(response);  
        }  


    }  


附:FullHttpRequest構成,因此一個FullHttpRequest會包含請求message的所有片段。

20140402151452921.png


來自:http://blog.csdn.net/suifeng3051/article/details/22800171

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!