现在是2018年1月11日18:12分,已经是下班时间了,小Alan今天给大家简单的介绍一下Netty,让大家以后在使用到Netty的时候能够有一定的了解和基础,这样深入学习Netty以及以后灵活应用这门技术也就不在话下了,万丈高楼平地起,程序猿们平时还是要注重积累,多花些时间在技术上面,如果实在对代码提不起兴趣就早点规划好自己的发展路线,死磕着也没什么必要,对自己没啥好处,但是如果你至少不讨厌编程,那么还是多多学习吧!

Netty是什么

Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

Netty的架构

Netty的特性

设计:

------统一的API,适用于不同的协议(阻塞和非阻塞)

------基于灵活、可扩展的事件驱动模型

------高度可定制的线程模型

------可靠的无连接数据Socket支持(UDP)

性能:

------更好的吞吐量,低延迟

------更省资源

------尽量减少不必要的内存拷贝

安全:

------完整的SSL/TLS和STARTTLS的支持

------能在Applet与谷歌Android的限制环境运行良好

健壮性:

------不再因过快、过慢或超负载连接导致OutOfMemoryError

------不再有在高速网络环境下NIO读写频率不一致的问题

易用:

------完善的Java doc,用户指南和样例

------简洁简单

------仅依赖于JDK1.5

Netty怎么用

小Alan教大家使用Netty3或Netty4发布Http协议服务接口,来引导大家进入Netty的世界。

Netty3实现Http协议服务接口步骤:

第一步:创建Http业务处理服务类,代码如下

 package com.alanlee.http;

 import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.DynamicChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
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.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; /**
* HTTP服务业务处理类.
*
* @author AlanLee
* @version 2018/01/11
*
*/
public class HttpServerHandler extends SimpleChannelUpstreamHandler
{ /**
* 日志类.
*/
protected static final Logger LOGGER = LoggerFactory.getLogger(HttpServerHandler.class); @Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
{ HttpRequest request = (HttpRequest) e.getMessage();
String method = request.getMethod().getName();
String url = request.getUri().toLowerCase();
System.out.println(method);
System.out.println(url); // 接收请求内容并打印
ChannelBuffer buffer = request.getContent();
String requestStr = new String(buffer.array(), "UTF-8");
System.out.println(requestStr); // 处理响应消息
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
ChannelBuffer responseBuffer = new DynamicChannelBuffer(2048);
responseBuffer.writeBytes("你是猪吗?".getBytes("UTF-8"));
response.setContent(responseBuffer);
// 返回内容的MIME类型
response.setHeader("Content-Type", "text/html; charset=UTF-8");
// 响应体的长度
response.setHeader("Content-Length", response.getContent().writerIndex());
Channel ch = e.getChannel(); // 响应给客户端
ChannelFuture f = ch.write(response); // 数据发送完毕,则关闭连接通道.
f.addListener(new ChannelFutureListener()
{
public void operationComplete(ChannelFuture future) throws Exception
{
future.getChannel().close();
}
});
} /**
* 发生异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
{
LOGGER.error("exceptionCaught(): ", e.getCause());
e.getCause().printStackTrace();
} }

第二步:创建Http管道类工厂用来联结Http业务处理服务类,代码如下

 package com.alanlee.http;

 import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder; /**
* HTTP管道类工厂.
*
* @author AlanLee
* @version 2018/01/11
*
*/
public class ServerPipelineFactory implements ChannelPipelineFactory
{ /**
* 获取管道.
*
* @return ChannelPipeline 管道
*/
public ChannelPipeline getPipeline()
{
ChannelPipeline pipeline = Channels.pipeline();
System.out.println("initChannel pipeline");
// 解码
pipeline.addLast("decoder", new HttpRequestDecoder(1024, 1024, 1000 * 1024));
// 编码
pipeline.addLast("encoder", new HttpResponseEncoder());
// 请求的业务类
pipeline.addLast("handler", new HttpServerHandler());
return pipeline;
} }

最后,让我们利用Netty3来发布Http协议服务接口,代码如下

 package com.alanlee.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; /**
* http服务启动类
*
* @author AlanLee
* @version 2018/01/11
*
*/
public class HttpServer
{ public static void main(String[] args)
{
ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
// 初始化channel的辅助类
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(new ServerPipelineFactory());
// 创建服务器端channel的辅助类,接收connection请求
bootstrap.bind(new InetSocketAddress(8080));
System.out.println("Start http server success!");
}
}

Netty4实现Http协议服务接口步骤:

第一步:创建Http业务处理服务类,代码如下

 package com.alanlee.netty2;

 import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.util.AsciiString; /**
* HttpServer业务处理
*
* @author AlanLee
* @version 2018/01/11
*
*/
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest>
{ private AsciiString contentType = HttpHeaderValues.TEXT_PLAIN; @Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception
{
String method = msg.method().name(); // 请求方式
String url = msg.uri().toLowerCase(); // 请求路径
System.out.println(method);
System.out.println(url); // 接收请求内容并打印
ByteBuf byteBuf = msg.content();
byte[] bytes = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(bytes);
String requestStr = new String(bytes, "UTF-8");
System.out.println(requestStr); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
Unpooled.wrappedBuffer("你才是猪!".getBytes())); HttpHeaders heads = response.headers();
// 返回内容的MIME类型
heads.add(HttpHeaderNames.CONTENT_TYPE, contentType + "; charset=UTF-8");
// 响应体的长度
heads.add(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
// 表示是否需要持久连接
heads.add(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); // 响应给客户端
ctx.write(response);
} /**
* 数据发送完毕,则关闭连接通道.
*/
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
{
System.out.println("channelReadComplete");
super.channelReadComplete(ctx);
ctx.flush();
} /**
* 发生异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
{
System.out.println("exceptionCaught");
if (null != cause)
cause.printStackTrace();
if (null != ctx)
ctx.close();
} }

最后,让我们利用Netty4来发布Http协议服务接口,代码如下

 package com.alanlee.netty2;

 import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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; /**
* 搭建HttpServer
*
* @author Alanlee
* @version 2018/01/11
*
*/
public class HttpServer
{ private final int port; public HttpServer(int port)
{
this.port = port;
} public static void main(String[] args) throws InterruptedException
{
new HttpServer(8081).start();
System.out.println("Start http server success!");
} public void start() throws InterruptedException
{
// 初始化channel的辅助类
ServerBootstrap b = new ServerBootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
b.group(group).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()
{
/**
* 初始化channel
*/
@Override
protected void initChannel(SocketChannel ch) throws Exception
{
System.out.println("initChannel ch:" + ch);
// 获取管道
ch.pipeline().addLast("decoder", new HttpRequestDecoder()) // 解码
.addLast("encoder", new HttpResponseEncoder()) // 编码
/* aggregator,消息聚合器(重要)。
Netty4中为什么能有FullHttpRequest这个东西,
就是因为有他,HttpObjectAggregator,如果没有他,
就不会有那个消息是FullHttpRequest的那段Channel,
同样也不会有FullHttpResponse,HttpObjectAggregator(512 * 1024)的参数含义是消息合并的数据大小,
如此代表聚合的消息内容长度不超过512kb。*/
.addLast("aggregator", new HttpObjectAggregator(512 * 1024))
.addLast("handler", new HttpHandler()); // 请求的业务类
} }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE); // 创建服务器端channel的辅助类,接收connection请求
b.bind(port).sync();
} }

检验成果

我们可以通过运行Netty3以及Netty4对应的HttpServer中的main方法来启动我们的Http服务器模拟。

启动Netty3提供的Http协议服务器,结果如下:

启动成功之后,我们利用Postman工具来做个简单的测试,注意这里Netty3使用的是8080端口,结果如下:

控制台输出内容如下:

我们再来启动Netty4提供的Http协议服务器,结果如下:

启动成功之后,我们利用Postman工具来做个简单的测试,注意这里Netty4使用的是8081端口,结果如下:

控制台输出内容如下:

这样,我们就成功的使用了Netty3和Netty4发布了Http协议服务接口,是不是很类似于我们的web后端开发,在平时的工作中如果遇到需要高并发的项目往往会需要将项目拆成后台节点来开发,此时可不仅仅web端需要提供接口,后台节点也是需要提供接口的,这时Netty就正好符合需求,所以大家可以花些时间去掌握Netty,建议掌握Netty4版本,这样版本升级的改动量会小很多,这里小Alan给大家开了扇门,把你引进门,修行在个人,如果你是一个热爱Java开发的人,也可以私聊Alan多多交流,只要Alan空闲的时候。

结束语:时间是最公平的,活一天就拥有24小时,差别只是珍惜。你若不相信努力和时光,时光一定第一个辜负你。有梦想就立刻行动,因为现在过的每一天,都是余生中最年轻的一天。

可爱博主:AlanLee

博客地址:http://www.cnblogs.com/AlanLee

本文出自博客园,欢迎大家加入博客园。

使用Netty3或Netty4发布Http协议服务的更多相关文章

  1. netty3升netty4一失眼成千古恨

    老项目是netty3的,本来想直接改到netty5,但是netty5居然是只支持jdk1.7,很奇怪jdk1.6和jdk1.8都不行..为了兼容jdk1.6加上netty4本来和netty5就差别不大 ...

  2. Azure机器学习入门(四)模型发布为Web服务

    接Azure机器学习(三)创建Azure机器学习实验,下一步便是真正地将Azure机器学习的预测模型发布为Web服务.要启用Web服务发布任务,首先点击底端导航栏的运行即"Run" ...

  3. 蓝萝卜blu netty3升netty4

    老项目是netty3的,本来想直接改到netty5,但是netty5居然是只支持jdk1.7,很奇怪jdk1.6和jdk1.8都不行..为了兼容jdk1.6加上netty4本来和netty5就差别不大 ...

  4. ArcGIS API for JavaScript(2)-ArcGIS Server发布要素图层服务

    1.前言 上一篇该系列的文章我们主要讲了一下基础Web地图搭建,这篇我们主要讲一下ArcGIS Server发布服务,并且如何调用服务.将自己的数据加载到Web地图当中来,实现Web端浏览数据. 2. ...

  5. 利用DotSpatial发布WMS, WFS服务

    我们遇到的几个给政府部门做的GIS系统,一般都只要面子,只要好看,领导高兴得不得了,点点这里点点那里,哟,这按钮一点还会转,领导开心得跟朵花似的...要是搞个各种分析什么的全堆上来,他就嫌烦了...这 ...

  6. wcf通过webHttpBinding方式发布rest web服务

    <system.serviceModel> <services> <service name="ServiceUpdater.ServiceUpdate&quo ...

  7. OpenLayers调用arcgis server发布的地图服务

    有两种方式可以调用arcgis server发布的地图服务,一种是rest,一种是wms.  地图的投影为900913,arcgis server为10.0版本,地图服务的空间参考为3857.   与 ...

  8. OpenLayers调用ArcGIS Server发布的WFS服务

    OpenLayers调用ArcGIS Server发布的WFS服务 原创: 蔡建良 2013-08-20 一. 开发环境 1) Openlayers2.13+arcgis server9.3 2) W ...

  9. geotrellis使用(三十一)使用geotrellis直接将GeoTiff发布为TMS服务

    前言 传统上我们需要先将Tiff中存储的影像等数据先切割成瓦片,而后再对外提供服务.这样的好处是服务器响应快,典型的用空间来换时间的操作.然而这样造成的问题是空间的巨大浪费,一般情况下均需要存储1-1 ...

随机推荐

  1. 2018沈阳网络赛 - Ka Chang KD树暴力

    题意:给你一棵树,n个点q次操作,操作1查询x子树深度为d的节点权值和,操作2查询子树x权值和 把每个点按(dfn,depth)的二维关系构造kd树,剩下的只需维护lazy标记即可 #include& ...

  2. PS2模拟器 PCSX2 新手向

    1.模拟器的下载 1.1百度网盘地址:http://pan.baidu.com/s/1i3kt7bJ (已经整合了PS2BIOS的模拟器下载,比较新的版本,适合新手) 1.2高端玩家可以下载: 官网g ...

  3. Mac下利用SSH进行传输文件(转)

    //1.从服务器上下载文件 scp username@servername:/path/filename /var/www/local_dir(本地目录) //例如scp root@192.168.0 ...

  4. mono for android 第四课--提示框(转)

    其实在VS中开发安卓代码和C#还是有一些相似性,刚开始我也不知道怎么弹出提示框,于是就百度了下,再加上个人的小聪明得到一下结果 builder.setTitle表示提示框的标题. setMessage ...

  5. Javac的命令(-Xlint)

    在OptionName类中的枚举定义如下: XLINT("-Xlint"), XLINT_CUSTOM("-Xlint:"), -Xlint     Enabl ...

  6. 1-1、create-react-app 配置 mobx

    1.用npx create-react-app my-app安装项目 2.cd my-app 3.执行 npm  run eject  让配置文件可见 4.npm install --saveDev ...

  7. msyql int(x) 中的x

    先看一个mysql表结构 Sql代码 CREATE   TABLE  `test` ( `TYPEID` int (2) ) ENGINE=MyISAM CHARSET=latin1; Sql代码   ...

  8. tomcat主页打不开,tomcat manager 配置,Failed to start component [StandardEngine[Catalina].

    Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/Serv]] ...

  9. ant使用小结

    使用builder.xml的方式:完成的工作:打jar包并运行,其中引用了第三方jar和配置文件: <?xml version="1.0" encoding="UT ...

  10. MVC缓存(二)

    依赖缓存: 1.监视特定的数据库表,当数据库表里数据发生变化时,自动删除缓存项,并向Cache中添加新的项. using System; using System.Collections.Generi ...