- 如何获取ctx的id
使用ctx.ctx.toString()就可以了
public void channelRead(ChannelHandlerContext ctx, Object msg) {//传来的消息包装成字节缓冲区String byteBuf = (String) msg;
// ByteBuf byteBuf = (ByteBuf) msg;//Netty提供了字节缓冲区的toString方法,并且可以设置参数为编码格式:CharsetUtil.UTF_8System.out.println("客户端读取服务返回的数据:" + byteBuf+" and ctx is "+ctx.toString());ctxOut=ctx;RESPSTR=byteBuf;}
结果如下
客户端读取服务返回的数据:0 and ctx is ChannelHandlerContext(NettyClientHandlerInner#0, [id: 0x59510140, L:/127.0.0.1:54769 - R:/127.0.0.1:1003])
- 阻塞执行问题
在启动了连接server后,如果是封装到一个方法里,程序是不能往下执行的,如下
如果把nettyClientHandlerInner.sendMSG(“write:0”);放在了client.connectToServer(nettyClientHandlerInner);后面,程序是执行到connectToServer就不会往下执行了
NettyClientHandlerInner nettyClientHandlerInner=new NettyClientHandlerInner();new Thread(new Runnable() {@Overridepublic void run() {nettyClientQA client = new nettyClientQA();nettyClientHandlerInner.sendMSG("write:0");client.connectToServer(nettyClientHandlerInner);}}).start();
上面代码执行到sendMSG的时候,会报错,因为还没有通道激活初始化,因此,解决暂时方法是,应该还有更好的解决方法,等后面想到了再更新
NettyClientHandlerInner nettyClientHandlerInner=new NettyClientHandlerInner();nettyClientQA client = new nettyClientQA();new Thread(new Runnable() {@Overridepublic void run() {new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}nettyClientHandlerInner.sendMSG("write:0");}}).start();client.connectToServer(nettyClientHandlerInner);}}).start();
- 如何捕获client handler的异常
加个内部类即可
package sample.appfunction.netty;import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.util.CharsetUtil;import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;public class nettyClientQA {public void connectToServer(NettyClientHandlerInner nettyClientHandler){EventLoopGroup workerGroup = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap(); // (1)b.group(workerGroup); // (2)b.channel(NioSocketChannel.class); // (3)b.option(ChannelOption.SO_KEEPALIVE, true); // (4)b.handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new LineBasedFrameDecoder(1024));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(nettyClientHandler);ch.pipeline().addLast(new ExceptionHandlingChannelHandler());}});// Start the client.ChannelFuture f = b.connect("127.0.0.1", 1003).sync(); // (5)f.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) {if (future.isSuccess()) {// 连接成功,无需重连System.out.println("connect to server success");} else {// 连接失败,进行重连System.out.println("connect to server failed,try it again");future.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {b.connect(); // 重新连接服务端}}, 1, TimeUnit.SECONDS); // 1秒后进行重连}}});// Wait until the connection is closed.f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {workerGroup.shutdownGracefully();}}public class ExceptionHandlingChannelHandler extends ChannelInboundHandlerAdapter {@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace(); // 打印异常堆栈跟踪System.out.println("发生异常");}}
}