您的位置:首页 > 理论基础 > 计算机网络

Netty之HTTP协议开发

2016-08-24 07:12 323 查看
最近学到的htttp协议开发,这个HTTP协议因为第一次接触不太好理解,网上看了很多教程,终于是明白了。

先将代码放在前面,大家可以对照的学习;

在本章开始之前,建议大家先明白HTTP协议的原理,这位大神的文章非常好,如果有不明白的可以看看。

由于netty天生就是异步事件驱动的架构,因此基于netty开发的HTTP协议也是异步非阻塞的,并且http协议栈无论在性能和可靠性上都表现非常优异,下面我们将进行netty HTTP协议开发之旅。

HTTP理解客户端和服务器端的交互步骤

客户端和服务器端的交互步骤如下:

1、Client向Server发送http请求。
2、Server端对http请求进行解析。
3、Server端向client发送http响应。
4、Client对http响应进行解析。


在这些步骤中会涉及到http请求的编码、解码,http响应的编码、解码。幸运的是,Netty已经为我们提供了这些工具,整个实例的逻辑图如下所示:



其中红色框中的4个类是Netty提供的,它们其实也是一种Handler,其中Encoder继承自ChannelOutboundHandler,Decoder继承自ChannelInboundHandler,它们的作用是:

1、HttpRequestEncoder:对httpRequest进行编码。
2、HttpRequestDecoder:把流数据解析为httpRequest。
3、HttpResponsetEncoder:对httpResponset进行编码。
4、HttpResponseEncoder:把流数据解析为httpResponse。


该实例涉及到的类有5个:HttpServer HttpServerInboundHandler HttpClient HttpClientInboundHandler ByteBufToBytes

场景描述

我们以文件服务器为例学习netty的http服务端入门开发,场景如下:文件服务器使用HTTP协议对外提供服务,当客户端通过浏览器访问文件服务器时,对访问路径进行检查,检查失败时返回403错误,该页无法访问;如果通过校验,以连接的方式打开当前文件目录,每个目录或者文件都是一个超链接,可以递归访问。如果是目录可以继续递归访问它下面的子目录,或者文件,如果是文件且可读,刚可以在浏览器端直接打开,或者通过【另存为】下载该文件。

代码讲解

代码太多了只对核心代码进行讲解,demo中我都做了详细的介绍,大家把代码下载下来仔细的看看。代码就2个文件不多。下面我们来看一下HttpFileServerHandler类

HttpFileServer类讲解

/**
* @author 作者 YYD
* @version 创建时间:2016年8月12日 上午11:10:18
* @function
*  文件服务器使用HTTP协议对外提供服务,当客户端通过浏览器访问文件服务器时,对访问路径进行检查,检查失败返回403错误,该页无法访问;
*  如果校验通过,以链接的方式打开当前文件目录,每个目录或者文件都是个超链接,可以递归访问。
*      如果是目录,可以继续递归访问它下面的子目录或者文件,如果是文件且可读,则可以在浏览器上直接打开,或者通过【目标另存为】下载该文件
*/
public class HttpFileServer {
//默认的url路径是:"/src/com/czh/server/"
private static final String DEFAULT_URL = "/src/com/czh/";

public void run(final int port,final String url) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {

@Override
protected void initChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());
//把多个消息转化成一个消息(FullHttpRequest或者FullHttpResponse),原因是HTTP解码器在每个HTTP消息中会生成多个消息对象。
ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());
//支持处理异步发送大数据文件,但不占用过多的内存,防止发生内存泄漏
ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
//这个是我们自定义的,处理文件服务器逻辑。主要功能还是在这个文件中
ch.pipeline().addLast("http-fileServerHandler", new HttpFileServerHandler(url));
}
});
ChannelFuture future  = b.bind("172.16.1.188",port).sync();//这里写你本机的IP地址
System.out.println("HTTP 文件目录服务器启动,网址是:"+"http://172.16.1.188:"+port+url);
future.channel().closeFuture().sync();
} catch (Exception e) {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}

}
public static void main(String[] args) throws Exception{

int port =  9090;
String url = DEFAULT_URL;
new HttpFileServer().run(port, url);
}
}


讲解:该类的核心代码在initChannel方法中,添加了不少handler处理器。

HttpRequestDecoder:作用是把流数据解析为httpRequest
HttpObjectAggregator:把多个消息转化成一个消息
HttpResponseEncoder:http服务器端对response编码
ChunkedWriteHandler:持处理异步发送大数据文件,但不占用过多的内存,防止发生内存泄漏


我们的核心功能还是在HttpFileServerHandler类中下面我们来看一下这个类。

HttpFileServerHandler讲解

这个类的代码太多放不开,我在代码中都做的详细的注释,大家看代码吧,这里就不赘述了。

运行结果



当我们输入错误的网址时,来看一下服务器的反映



当我们输入正确的网址的时候来看一下服务器的反映



作者的失误

本代码有一个地方我没弄好,就是链接不能点击。不好意思,我本身对html不熟悉,调了半天没弄好,有会的朋友告诉我。

结尾

好了就讲到这里吧,一开始学习netty真难学,慢慢的入门了。加油,坚持就会有奇迹!

点击代码下载.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  http协议 netty