Netty中的SimpleChannelInboundHandler的通信过程
先看例子代码:
public class ClientHandler extends SimpleChannelInboundHandler<Object>{
@Override
protected void channelRead0(ChannelHandlerContext arg0, Object arg1) throws Exception {
}
/**
* 客户端读取服务端信息
*/
@Override
public void channelRead(ChannelHandlerContext arg0, Object arg1) throws Exception {
System.out.println("客户端开始读取服务端过来的信息");
ByteBuf buf = (ByteBuf) arg1;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
System.out.println(new String(bytes));
}
/**
* 客户端连接到服务端后进行
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端传给服务端");
String string = "to Server";
ByteBuf buf = Unpooled.buffer(string.length());
buf.writeBytes(string.getBytes());
ctx.writeAndFlush(buf);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
}
}
这是客户端的处理代码,其中的基本方法用法如下:
/*
* 覆盖了 channelRead0() 事件处理方法。
* 每当从服务端读到客户端写入信息时,
* 其中如果你使用的是 Netty 5.x 版本时,
* 需要把 channelRead0() 重命名为messageReceived()
*/
@Override
protected void channelRead0(ChannelHandlerContext arg0, String arg1)
throws Exception {
// TODO Auto-generated method stub
}
/*
* 覆盖channelActive 方法在channel被启用的时候触发(在建立连接的时候)
* 覆盖了 channelActive() 事件处理方法。服务端监听到客户端活动
*/
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
super.channelActive(ctx);
}
/*
* (non-Javadoc)
* 覆盖了 handlerAdded() 事件处理方法。
* 每当从服务端收到新的客户端连接时
*/
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
super.handlerAdded(ctx);
}
/*
* (non-Javadoc)
* .覆盖了 handlerRemoved() 事件处理方法。
* 每当从服务端收到客户端断开时
*/
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
super.handlerRemoved(ctx);
}
/*
* exceptionCaught() 事件处理方法是当出现 Throwable 对象才会被调用,
* 即当 Netty 由于 IO 错误或者处理器在处理事件时抛出的异常时。
* 在大部分情况下,捕获的异常应该被记录下来并且把关联的 channel 给关闭掉。
* 然而这个方法的处理方式会在遇到不同异常的情况下有不同的实现,
* 比如你可能想在关闭连接之前发送一个错误码的响应消息。
*/
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
super.exceptionCaught(ctx, cause);
}
也就是当客户端连接到服务端时,会先执行channelActive方法,当有数据传递过来时,再执行channelRead
服务端代码例子:
public class ServerHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void channelRead0(ChannelHandlerContext arg0, Object arg1) throws Exception {
}
@Override
public void channelRead(ChannelHandlerContext arg0, Object arg1) throws Exception {
System.out.println("服务端传递");
ByteBuf buf = (ByteBuf) arg1;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
System.out.println(new String(bytes));
String string = "to client";
ByteBuf writebuf = Unpooled.copiedBuffer(string.getBytes());
arg0.writeAndFlush(writebuf);//发送到客户端
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("ServerHandler.channelReadComplete()");
ctx.flush();
}
}