Netty学习:搭建一个简单的Netty服务
Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。Netty 已逐渐成为 Java NIO 编程的首选框架。
项目官方地址:http://netty.io/index.html
一. Netty 的优点:API 使用简单,开发门槛低;
功能强大,预置了多种编解码功能,支持多种主流协议;
定制能力强,可以通过 ChannelHandler 对通信框架进行灵活的扩展;
性能高,通过与其它业界主流的 NIO 框架对比,Netty 的综合性能最优;
社区活跃,版本迭代周期短,发现的 BUG 可以被及时修复,同时,更多的新功能会被加入;
经历了大规模的商业应用考验,质量得到验证。在互联网、大数据、网络游戏、企业应用、电信软件等众多行业得到成功商用,证明了它完全满足不同行业的商用标准。
二. 搭建Netty服务:添加pom依赖
Pom代码
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.0.Final</version>
</dependency>
SimpleServer(服务端)
Java代码
packagecom.yingjun.netty.server;
importio.netty.bootstrap.ServerBootstrap;
importio.netty.channel.ChannelFuture;
importio.netty.channel.ChannelInitializer;
importio.netty.channel.ChannelOption;
importio.netty.channel.EventLoopGroup;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;
/**
*
*Netty中,通讯的双方建立连接后,会把数据按照ByteBuf的方式进行传输,
*例如http协议中,就是通过HttpRequestDecoder对ByteBuf数据流进行处理,转换成http的对象。
*
*/
publicclassSimpleServer{
privateintport;
publicSimpleServer(intport){
this.port=port;
}
publicvoidrun()throwsException{
//EventLoopGroup是用来处理IO操作的多线程事件循环器
//bossGroup用来接收进来的连接
EventLoopGroupbossGroup=newNioEventLoopGroup();
//workerGroup用来处理已经被接收的连接
EventLoopGroupworkerGroup=newNioEventLoopGroup();
try{
//启动NIO服务的辅助启动类
ServerBootstrapb=newServerBootstrap();
b.group(bossGroup,workerGroup)
//配置Channel
.channel(NioServerSocketChannel.class)
.childHandler(newChannelInitializer<SocketChannel>(){
@Override
publicvoidinitChannel(SocketChannelch)throwsException{
//注册handler
ch.pipeline().addLast(newSimpleServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG,128)
.childOption(ChannelOption.SO_KEEPALIVE,true);
//绑定端口,开始接收进来的连接
ChannelFuturef=b.bind(port).sync();
//等待服务器socket关闭。
f.channel().closeFuture().sync();
}finally{
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
publicstaticvoidmain(String[]args)throwsException{
newSimpleServer(9999).run();
}
}
SimpleServerHandler(服务端请求处理Handler)
Java代码
packagecom.yingjun.netty.server;
importio.netty.buffer.ByteBuf;
importio.netty.channel.ChannelHandlerContext;
importio.netty.channel.ChannelInboundHandlerAdapter;
publicclassSimpleServerHandlerextendsChannelInboundHandlerAdapter{
@Override
publicvoidchannelRead(ChannelHandlerContextctx,Objectmsg)throwsException{
System.out.println("SimpleServerHandler.channelRead");
ByteBufresult=(ByteBuf)msg;
byte[]result1=newbyte[result.readableBytes()];
//msg中存储的是ByteBuf类型的数据,把数据读取到byte[]中
result.readBytes(result1);
StringresultStr=newString(result1);
//接收并打印客户端的信息
System.out.println("Clientsaid:"+resultStr);
//释放资源,这行很关键
result.release();
//向客户端发送消息
Stringresponse="helloclient!";
//在当前场景下,发送的数据必须转换成ByteBuf数组
ByteBufencoded=ctx.alloc().buffer(4*response.length());
encoded.writeBytes(response.getBytes());
ctx.write(encoded);
ctx.flush();
}
@Override
publicvoidexceptionCaught(ChannelHandlerContextctx,Throwablecause)throwsException{
//当出现异常就关闭连接
cause.printStackTrace();
ctx.close();
}
@Override
publicvoidchannelReadComplete(ChannelHandlerContextctx)throwsException{
ctx.flush();
}
}
SimpleServer(客户端)
Java代码
packagecom.yingjun.netty.server;
importio.netty.bootstrap.Bootstrap;
importio.netty.bootstrap.ServerBootstrap;
importio.netty.channel.ChannelFuture;
importio.netty.channel.ChannelInitializer;
importio.netty.channel.ChannelOption;
importio.netty.channel.EventLoopGroup;
importio.netty.channel.nio.NioEventLoopGroup;
importio.netty.channel.socket.SocketChannel;
importio.netty.channel.socket.nio.NioServerSocketChannel;
importio.netty.channel.socket.nio.NioSocketChannel;
publicclassSimpleClient{
publicvoidconnect(Stringhost,intport)throwsException{
EventLoopGroupworkerGroup=newNioEventLoopGroup();
try{
Bootstrapb=newBootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE,true);
b.handler(newChannelInitializer<SocketChannel>(){
@Override
publicvoidinitChannel(SocketChannelch)throwsException{
ch.pipeline().addLast(newSimpleClientHandler());
}
});
//Starttheclient.
ChannelFuturef=b.connect(host,port).sync();
//Waituntiltheconnectionisclosed.
f.channel().closeFuture().sync();
}finally{
workerGroup.shutdownGracefully();
}
}
publicstaticvoidmain(String[]args)throwsException{
SimpleClientclient=newSimpleClient();
client.connect("127.0.0.1",9999);
}
}
SimpleServerHandler(客户端请求处理Handlerspringmvc+mybatis+spring 整合下载地址)
Java代码
packagecom.yingjun.netty.server;
importio.netty.buffer.ByteBuf;
importio.netty.channel.ChannelHandlerContext;
importio.netty.channel.ChannelInboundHandlerAdapter;
publicclassSimpleClientHandlerextendsChannelInboundHandlerAdapter{
@Override
publicvoidchannelRead(ChannelHandlerContextctx,Objectmsg)throwsException{
System.out.println("SimpleClientHandler.channelRead");
ByteBufresult=(ByteBuf)msg;
byte[]result1=newbyte[result.readableBytes()];
result.readBytes(result1);
System.out.println("Serversaid:"+newString(result1));
result.release();
}
@Override
publicvoidexceptionCaught(ChannelHandlerContextctx,Throwablecause)throwsException{
//当出现异常就关闭连接
cause.printStackTrace();
ctx.close();
}
//连接成功后,向server发送消息
@Override
publicvoidchannelActive(ChannelHandlerContextctx)throwsException{
Stringmsg="helloServer!";
ByteBufencoded=ctx.alloc().buffer(4*msg.length());
encoded.writeBytes(msg.getBytes());
ctx.write(encoded);
ctx.flush();
}
}
运行结果:
Java代码
SimpleClientHandler.channelRead
Serversaid:helloclient!
------------------------------------------
SimpleServerHandler.channelRead
Clientsaid:helloServer!
SimpleServerHandler.channelRead
Clientsaid:helloServer!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。