TimeServer:
public class TimeServer {
public void bind(int port) throws Exception {
// 配置服務(wù)端的NIO線程組
//用于網(wǎng)絡(luò)事件處理
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//啟動(dòng)NIO服務(wù)端的輔助啟動(dòng)類
ServerBootstrap b = new ServerBootstrap();
//將創(chuàng)建的channel作為ServerSocketChannel
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChildChannelHandler());
// 綁定端口,同步等待成功
ChannelFuture f = b.bind(port).sync();
// 等待服務(wù)端監(jiān)聽端口關(guān)閉
f.channel().closeFuture().sync();
} finally {
// 優(yōu)雅退出诡必,釋放線程池資源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new TimeServerHandler());
}
}
public static void main(String[] args) throws Exception {
int port=8080;
if(args!=null&&args.length>0){
try {
port=Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
new TimeServer().bind(port);
}
}
TimeServerHandler(channelHandlerAdapter部分方法只有5.0.0才有):
public class TimeServerHandler extends ChannelHandlerAdapter {
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("The time server receive order : " + body);
String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(
System.currentTimeMillis()).toString() : "BAD ORDER";
ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(resp);
}
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//netty的消息不直接寫入channel,它放在緩沖數(shù)組,調(diào)用flush()才寫入
ctx.flush();
}
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}
}
TimeClient:
public class TimeClient {
public void connect(int port, String host) throws Exception {
// 配置客戶端NIO線程組
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
//初始化時(shí)將handler設(shè)置到ChannelPipeline
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
});
// 發(fā)起異步連接操作
ChannelFuture f = b.connect(host, port).sync();
// 當(dāng)代客戶端鏈路關(guān)閉
f.channel().closeFuture().sync();
} finally {
// 優(yōu)雅退出员舵,釋放NIO線程組
group.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
new TimeClient().connect(port, "127.0.0.1");
}
}
TimeClientHandler:
public class TimeClientHandler extends ChannelHandlerAdapter {
private static final Logger logger = Logger
.getLogger(TimeClientHandler.class.getName());
private final ByteBuf firstMessage;
/**
* Creates a client-side handler.
*/
public TimeClientHandler() {
byte[] req = "QUERY TIME ORDER".getBytes();
firstMessage = Unpooled.buffer(req.length);
firstMessage.writeBytes(req);
}
//客戶端和服務(wù)端TCP鏈路建立成功后調(diào)用此方法
public void channelActive(ChannelHandlerContext ctx) {
//通過此方法將消息發(fā)送給服務(wù)端
ctx.writeAndFlush(firstMessage);
}
//服務(wù)端返回應(yīng)答消息調(diào)用此方法
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("Now is : " + body);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// 釋放資源
logger.warning("Unexpected exception from downstream : "
+ cause.getMessage());
ctx.close();
}
}