前提:假设你的客户端和服务端已经写好了的情况下
1.短线重连是客户端的事情——————》客户端一般这样写
客户端:
private Channel channel;
private Bootstrap bootstrap;
public void client() throws InterruptedException {
String ip = "localhost";
Integer port = 9898;
bootstrap = new Bootstrap();
System.out.println(this.getClass());
NioEventLoopGroup loopGroup = new NioEventLoopGroup();
NettyTest t = this;
bootstrap.group(loopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.SO_BACKLOG, 1000)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(2048))
.handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) throws Exception {
// 自己的处理器
channel.pipeline().addLast(new TestClientHandler(t));
}
});
try {
ChannelFuture channelFuture = bootstrap.connect(ip,port).sync();
clientChannelFuture.channel().closeFuture().sync()
} finally {
/**优雅退出,释放NIO线程组*/
loopGroup.shutdownGracefully();
}
处理器:
public class TestClientHandler extends ChannelInboundHandlerAdapter {
// NettyTest nettyTest;
//
// public TestClientHandler(NettyTest nettyTest) {
// this.nettyTest = nettyTest;
// }
NettyTest nettyTest;
public TestClientHandler(netty.test.NettyTest client) {
// super("client");
this.nettyTest = client;
}
public TestClientHandler(){}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接成功");
String reqMsg = "我是客户端 110 " + Thread.currentThread().getName();
byte[] reqMsgByte = reqMsg.getBytes("UTF-8");
ByteBuf reqByteBuf = Unpooled.buffer(reqMsgByte.length);
/**
* writeBytes:将指定的源数组的数据传输到缓冲区
* 调用 ChannelHandlerContext 的 writeAndFlush 方法将消息发送给服务器
*/
reqByteBuf.writeBytes(reqMsgByte);
ctx.writeAndFlush(reqByteBuf);
}
/**
* 当服务端返回应答消息时,channelRead 方法被调用,从 Netty 的 ByteBuf 中读取并打印应答消息
*/
@Override
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(Thread.currentThread().getName() + ",Server return Message:" + body);
// ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
System.out.println("服务端断开:" + ctx.channel().remoteAddress());
//TODO 断开后的重连接
}
/**
* 当发生异常时,打印异常 日志,释放客户端资源
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// /**释放资源*/
// ctx.close();
}
断线重连改写
客户端:
private Channel channel;
private Bootstrap bootstrap;
ClientChannelFuture clientChannelFuture;
public void client() throws InterruptedException {
String ip = "localhost";
Integer port = 9898;
bootstrap = new Bootstrap();
System.out.println(this.getClass());
NioEventLoopGroup loopGroup = new NioEventLoopGroup();
NettyTest t = this;
bootstrap.group(loopGroup)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.SO_BACKLOG, 1000)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(2048))
.handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel channel) throws Exception {
// channel.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
// String delimiter = "\r\n";
// int length = 40960;
// ByteBuf byteBuf = Unpooled.copiedBuffer(delimiter, CharsetUtil.UTF_8);
// channel.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(length, byteBuf));
channel.pipeline().addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
channel.pipeline().addLast(new TestClientHandler(t));
}
});
try {
this.doConnect();
clientChannelFuture.channel().closeFuture().sync();
} catch (Exception e) {
log.info("启动出错 e", e);
} finally { //优雅关闭功能
log.info("SecureDeviceServer run finnally shutdown.");
// loopGroup.shutdownGracefully();
}
}
protected void doConnect() {
if (channel != null && channel.isActive()) {
return;
}
clientChannelFuture = bootstrap.connect("127.0.0.1", 9898);
clientChannelFuture.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture futureListener) throws Exception {
if (futureListener.isSuccess()) {
channel = futureListener.channel();
System.out.println("Connect to server successfully!");
} else {
System.out.println("Failed to connect to server, try connect after 10s");
futureListener.channel().eventLoop().schedule(new Runnable() {
@Override
public void run() {
doConnect();
}
}, 10, TimeUnit.SECONDS);
}
}
});
}
处理器:
NettyTest nettyTest;
//
// public TestClientHandler(NettyTest nettyTest) {
// this.nettyTest = nettyTest;
// }
NettyTest nettyTest;
public TestClientHandler(netty.test.NettyTest client) {
// super("client");
this.nettyTest = client;
}
public TestClientHandler(){}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接成功");
String reqMsg = "我是客户端 110 " + Thread.currentThread().getName();
byte[] reqMsgByte = reqMsg.getBytes("UTF-8");
ByteBuf reqByteBuf = Unpooled.buffer(reqMsgByte.length);
/**
* writeBytes:将指定的源数组的数据传输到缓冲区
* 调用 ChannelHandlerContext 的 writeAndFlush 方法将消息发送给服务器
*/
reqByteBuf.writeBytes(reqMsgByte);
ctx.writeAndFlush(reqByteBuf);
}
/**
* 当服务端返回应答消息时,channelRead 方法被调用,从 Netty 的 ByteBuf 中读取并打印应答消息
*/
@Override
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(Thread.currentThread().getName() + ",Server return Message:" + body);
// ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
System.out.println("服务端断开:" + ctx.channel().remoteAddress());
//TODO 断开后的重连接
// 加入短线重连
nettyTest.doConnect();
}
/**
* 当发生异常时,打印异常 日志,释放客户端资源
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
// /**释放资源*/
// ctx.close();
}