2021-03-02

天气:晴

今天学习内容:

一、Netty的handler链调用机制

1.netty的逐渐主要有Channel、EventLoop、ChannelFuture、ChanneHandler、ChannelPipe等

2.ChannelHandler充当了处理入站出站数据应用程序逻辑的容器

编写server:

public class MyServer{
	public static void main(String[] args) throws Exception{
	//创建两个组
		EventLoopGroup bossGroup = new NioEventLoopGroup(1);
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try{
		ServerBootstrap serverBootstrap = new ServerBootstrap();
				serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new MyServerInitializer());//自定义一个初始化类
		
		ChannelFuture channelFuture = serverBootstrap.bind(7000).sync();
		channelFuture.channel().closeFuture().sync();
		
		}finally{
		bossGroup.shutdownGracefully();
		workerGroup.shutdownGracefully();
		}
	}
}
		
		

编写一个服务器初始化类MyServerInitializer

public class MyServerInitializer extends ChannelInitializer<SockerChannel>{
	@Override
	protected void initChannel(SocketChannel ch) throw Exception{
	ChannelPipeline pipeline = ch.pipeline();
	//入站的handler 进行解码MyByteTolongDecoder
	pipeline.addLast(new MyByteTolongDecoder
());
	//编写一个自定义handler处理业务逻辑
	pipeline.addLast(new MyServerHandler
());

}

编写一个MyByteTolongDecoder

public class MyByteTolongDecoder extends ByteToMessageDecoder{

	@Override
	protected void decode(ChannelHandlerContext ctx,ByteBuf in, List<Object> out)throws Exception{
	//ctx是上下文对象
	//in是入站的bytebuf
	//out是list集合,将解码后的数据传给下一个handler
		System.out.println("MyByteTolongDecoder
类的decode方法被调用");
		//因为long是八个字节
		if(in.readableBytes() >= 8){
		out.add(in.readLong());
	}
	}

编写一个MyServerHandler

public class MyServerHandler extends SimpleChannelInboundHandler<long>{
	@Override
	protected coid channelRead0(ChannelHandlerContext ctx,Long msg) throws Exception{
		System.out.println("从客户端" + ctx.channel().remoteAddress() + "读取到long" +msg);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception{
	cause.printStackTrace();
	ctx.close();
	}
}

编写一个客户端MyClient

public class MyClient{
	public static void main(String[] args) throws Exception{
		EcentLoopGroup group = new NioEVentLoopGroup();
	try{
	Bootstrap bootstrap = new Bootstrap();
	bootstap.group(group).channel(NioSocketChannel.class).handler(new MyClientInitializer());//自定义一个初始化类
	//绑定地址拿到一个channelFuture
	ChannelFuture channelFuture = bootstrap.connect("locahost",7000).sync();
	channelFuture.channel().closeFuture().sync();
	}finally{
	group.shutdownGracefully();
	}
}

编写一个MyClientInitializer

public class MyClientInitializer extends ChannelInitializer<SocketChannel>{
	@Override
	protected void initChannel(SocketChannel ch) throws Exception{
	ChannelPopeline pipeline = ch.pipeline();
	//加入一个出站handler对数据进行一个编码
	pipeline.addLast(new MyLongToByteEncoder());
	//加入一个自定义的handler,处理业务
	pipeline.addLast(new MyClientHandler());

编写一个出站编码的handler

public class MyLongToByteEncoder extends MessageToByteEncoder<Long>{
	@Override
	protected void encode(ChannelHandlerContext ctx,Long msg,ByteBuf out) throws Exception{
	System.out.println("MyLongToByteEncoder类的encode方法被调用");
	System.out.println("msg=" + msg);
	out.writeLong(msg);
	}
	}

编写一个处理业务的MyClientHandler

public class MyClientHandler extends SimpleChannelInboundHandler<Long>{
	@Override
	protected void channelRead0(ChannelHandlerContext ctx,Long msg) throws Exception{
	
	}
	//重写channelActive发送数据
	@override
	public void channelActive(ChannelHandlerContext ctx) throws Exception{
	System.out.println("MyClientHandler 发送数据");
	//ctx.writeAndflush(Unpooled.copiedBuffer("dwwdw"));
	ctx.writeAndFlush(1232425L);//直接发送一个long
}

拓展:

1.发送的内容如果不符合编码器泛型,会跳过处理直接传递给下一个handler;
2.编码器每读取一次都会传递给下一个handler,所以可能会出现多次调用handler的情况,比如上面发送的不是一个long而是一个长字符串,会触发多次MyServerHandler

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值