接上篇
本篇说明下,在所有inhandler中的最后一个需要写个ctx.write(),这样能进入outhandler的write()中ctx.write()操作,否则,无法发送数据到客户断
package com.wang.netty4Out.second;
import org.apache.cassandra.cli.CliParser.newColumnFamily_return;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
/**
* 这个用于测试handler的传递功能
* @author wangzg
*
* 本例子使用的是 实现的handler中,各个函数都是先super,然后打印,除了handler1中的channelRead,这样打印出的顺序是,先2后1,也就是最后加进去的,先做,先进去的后做,跟
* 网上的不一致
*
* 本例子中各个handler中的方法,都在最后使用了super()的方法,顺序和网上的一致
*
* 本例子将用于数据解析
* 本例的例子是inhandler2 和inhandler3都发送了数据,但是客户断接收的时候,是连在一起的,因此这里需要想办法,也就是连包拆包
*
* 本例子发现个问题,在Inhandler中都可以使用ctx.writeAndflush(msg),但这样的做法会造成,如果有outhandler的时候,发送回客户端的数据,有多个
* outhandler发回的数据(都是一样的,个数是inhander中ctx.writeAndFlush()个数),如何解决的,既然需要msg向后传递,又不能
* 有多个重复数据发回,那就需要在inhandler的channelRead()不能使用super.channelread(),而是使用ctx.fireChannelRead(加工过的msg)
* 每一次inhandler的super()或者ctx.firechannelread,操作触发outhandler的write()操作和下一个inhandler的channelread操作,每一次
* inhandler的ctx.write()操作,触发outhandler的write()中的ctx.write()操作
*/
public class WangNetty4Out2Server {
private static final Logger LOGGER = LoggerFactory.getLogger(WangNetty4Out2Server.class);
public void start(int port){
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup work = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
try {
bootstrap.group(boss, work)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
// .option(ChannelOption.SO_TIMEOUT, 5 * 1000)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.SO_RCVBUF, 10 * 1024)
.childOption(ChannelOption.SO_SNDBUF, 10 * 1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new WangOuthandler1());
sc.pipeline().addLast(new WangInHandler1());
sc.pipeline().addLast(new WangInHandler2());
sc.pipeline().addLast(new WangInHandler3());
// sc.pipeline().addLast(new WangOuthandler1());
}
});
ChannelFuture future = bootstrap.bind(port).sync();
future.channel().closeFuture().sync();
} catch (Exception e) {
LOGGER.error("server 启动失败",e);
}finally{
boss.shutdownGracefully();
work.shutdownGracefully();
}
}
public static void main(String[] args) {
WangNetty4Out2Server server = new WangNetty4Out2Server();
server.start(8085);
}
}
package com.wang.netty4Out.second;
import org.apache.cassandra.utils.OutputHandler.SystemOutput;
import com.wang.netty4.six.NettyUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class WangInHandler1 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelRead");
System.out.println(" WangInHandler1 receive:"+NettyUtil.parseByteBufMsg(msg));
ctx.fireChannelRead(msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelReadComplete");
super.channelReadComplete(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 exceptionCaught");
super.exceptionCaught(ctx, cause);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelActive");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelInactive");
super.channelInactive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelRegistered");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelUnregistered");
super.channelUnregistered(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 channelWritabilityChanged");
super.channelWritabilityChanged(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler1 userEventTriggered");
super.userEventTriggered(ctx, evt);
}
}
package com.wang.netty4Out.second;
import com.wang.netty4.six.NettyUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class WangInHandler2 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelRead");
System.out.println(" WangInHandler2 receive:"+NettyUtil.parseByteBufMsg(msg));
ctx.fireChannelRead(NettyUtil.packageStringToByteBuf("I am handler2"));
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelReadComplete");
super.channelReadComplete(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 exceptionCaught");
super.exceptionCaught(ctx, cause);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelActive");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelInactive");
super.channelInactive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelRegistered");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelUnregistered");
super.channelUnregistered(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 channelWritabilityChanged");
super.channelWritabilityChanged(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler2 userEventTriggered");
super.userEventTriggered(ctx, evt);
}
}
package com.wang.netty4Out.second;
import com.wang.netty4.six.NettyUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class WangInHandler3 extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelRead");
System.out.println("WangInHandler3 channelRead receive:"+NettyUtil.parseByteBufMsg(msg));
ctx.writeAndFlush(NettyUtil.packageStringToByteBuf(" I am inHandler3"));//最后一个indhandler需要ctx.write()而不能使用下面2行
// ctx.fireChannelRead(NettyUtil.packageStringToByteBuf(" I am inHandler3"));
// super.channelRead(ctx, msg);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelReadComplete");
super.channelReadComplete(ctx);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 exceptionCaught");
super.exceptionCaught(ctx, cause);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelActive");
super.channelActive(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelInactive");
super.channelInactive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelRegistered");
super.channelRegistered(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelUnregistered");
super.channelUnregistered(ctx);
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 channelWritabilityChanged");
super.channelWritabilityChanged(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
throws Exception {
// TODO Auto-generated method stub
System.out.println(" WangInHandler3 userEventTriggered");
super.userEventTriggered(ctx, evt);
}
}
package com.wang.netty4Out.second;
import java.net.SocketAddress;
import com.wang.netty4.six.NettyUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
public class WangOuthandler1 extends ChannelOutboundHandlerAdapter{
@Override
public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) throws Exception {
System.out.println(" WangOuthandler1 bind localAddress:"+localAddress.toString());
super.bind(ctx, localAddress, promise);
}
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)throws Exception {
System.out.println(" WangOuthandler1 connect remoteAddress:"+remoteAddress.toString()+" localAddress:"+localAddress.toString());
super.connect(ctx, remoteAddress, localAddress, promise);
}
@Override
public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
throws Exception {
System.out.println(" WangOuthandler1 ctx");
super.disconnect(ctx, promise);
}
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
System.out.println(" WangOuthandler1 close");
super.close(ctx, promise);
}
@Override
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
throws Exception {
System.out.println(" WangOuthandler1 deregister");
super.deregister(ctx, promise);
}
public void read(ChannelHandlerContext ctx) throws Exception {
System.out.println(" WangOuthandler1 read");
super.read(ctx);
}
@Override
public void write(ChannelHandlerContext ctx, Object msg,
ChannelPromise promise) throws Exception {
System.out.println(" WangOuthandler1 write");
System.out.println("WangOuthandler1 receive " +NettyUtil.parseByteBufMsg(msg));
ctx.writeAndFlush(NettyUtil.packageStringToByteBuf("WangOuthandler1"));
super.write(ctx, msg, promise);
}
public void flush(ChannelHandlerContext ctx) throws Exception {
System.out.println(" WangOuthandler1 flush");
super.flush(ctx);
}
}