來源:zzy7075 發(fā)布時(shí)間:2018-11-21 15:54:15 閱讀量:1102
Netty 是一個(gè)基于 JAVA NIO 類庫的異步通信框架,它的架構(gòu)特點(diǎn)是:異步非阻塞、基于事件驅(qū)動、高性能、高可靠性和高可定制性。換句話說,Netty是一個(gè)NIO框架,使用它可以簡單快速地開發(fā)網(wǎng)絡(luò)應(yīng)用程序,比如客戶端和服務(wù)端的協(xié)議。Netty大大簡化了網(wǎng)絡(luò)程序的開發(fā)過程比如TCP和UDP的 Socket的開發(fā)。Netty 已逐漸成為 Java NIO 編程的首選框架。
項(xiàng)目官方地址:http://netty.io/index.html
API 使用簡單,開發(fā)門檻低;
功能強(qiáng)大,預(yù)置了多種編解碼功能,支持多種主流協(xié)議;
定制能力強(qiáng),可以通過 ChannelHandler 對通信框架進(jìn)行靈活的擴(kuò)展;
性能高,通過與其它業(yè)界主流的 NIO 框架對比,Netty 的綜合性能最優(yōu);
社區(qū)活躍,版本迭代周期短,發(fā)現(xiàn)的 BUG 可以被及時(shí)修復(fù),同時(shí),更多的新功能會被加入;
經(jīng)歷了大規(guī)模的商業(yè)應(yīng)用考驗(yàn),質(zhì)量得到驗(yàn)證。在互聯(lián)網(wǎng)、大數(shù)據(jù)、網(wǎng)絡(luò)游戲、企業(yè)應(yīng)用、電信軟件等眾多行業(yè)得到成功商用,證明了它完全滿足不同行業(yè)的商用標(biāo)準(zhǔn)。
添加pom依賴
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.0.Final</version>
</dependency>
SimpleServer(服務(wù)端)
package com.yingjun.netty.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
*
* Netty中,通訊的雙方建立連接后,會把數(shù)據(jù)按照ByteBuf的方式進(jìn)行傳輸,
* 例如http協(xié)議中,就是通過HttpRequestDecoder對ByteBuf數(shù)據(jù)流進(jìn)行處理,轉(zhuǎn)換成http的對象。
*
*/
public class SimpleServer {
private int port;
public SimpleServer(int port) {
this.port = port;
}
public void run() throws Exception {
//EventLoopGroup是用來處理IO操作的多線程事件循環(huán)器
//bossGroup 用來接收進(jìn)來的連接
EventLoopGroup bossGroup = new NioEventLoopGroup();
//workerGroup 用來處理已經(jīng)被接收的連接
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//啟動 NIO 服務(wù)的輔助啟動類
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
//配置 Channel
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// 注冊handler
ch.pipeline().addLast(new SimpleServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 綁定端口,開始接收進(jìn)來的連接
ChannelFuture f = b.bind(port).sync();
// 等待服務(wù)器 socket 關(guān)閉 。
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new SimpleServer(9999).run();
}
}
SimpleServerHandler(服務(wù)端請求處理Handler)
package com.yingjun.netty.server;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("SimpleServerHandler.channelRead");
ByteBuf result = (ByteBuf) msg;
byte[] result1 = new byte[result.readableBytes()];
// msg中存儲的是ByteBuf類型的數(shù)據(jù),把數(shù)據(jù)讀取到byte[]中
result.readBytes(result1);
String resultStr = new String(result1);
// 接收并打印客戶端的信息
System.out.println("Client said:" + resultStr);
// 釋放資源,這行很關(guān)鍵
result.release();
// 向客戶端發(fā)送消息
String response = "hello client!";
// 在當(dāng)前場景下,發(fā)送的數(shù)據(jù)必須轉(zhuǎn)換成ByteBuf數(shù)組
ByteBuf encoded = ctx.alloc().buffer(4 * response.length());
encoded.writeBytes(response.getBytes());
ctx.write(encoded);
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 當(dāng)出現(xiàn)異常就關(guān)閉連接
cause.printStackTrace();
ctx.close();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
}
SimpleServer(客戶端)
package com.yingjun.netty.server;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.channel.socket.nio.NioSocketChannel;
public class SimpleClient {
public void connect(String host, int port) throws Exception {
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new SimpleClientHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync();
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
SimpleClient client=new SimpleClient();
client.connect("127.0.0.1", 9999);
}
}
SimpleServerHandler(客戶端請求處理Handler)
package com.yingjun.netty.server;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class SimpleClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("SimpleClientHandler.channelRead");
ByteBuf result = (ByteBuf) msg;
byte[] result1 = new byte[result.readableBytes()];
result.readBytes(result1);
System.out.println("Server said:" + new String(result1));
result.release();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// 當(dāng)出現(xiàn)異常就關(guān)閉連接
cause.printStackTrace();
ctx.close();
}
// 連接成功后,向server發(fā)送消息
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String msg = "hello Server!";
ByteBuf encoded = ctx.alloc().buffer(4 * msg.length());
encoded.writeBytes(msg.getBytes());
ctx.write(encoded);
ctx.flush();
}
}
運(yùn)行結(jié)果:
SimpleClientHandler.channelRead
Server said:hello client!
------------------------------------------
SimpleServerHandler.channelRead
Client said:hello Server!
SimpleServerHandler.channelRead
Client said:hello Server!