Netty:ChannelInitializer添加到ChannelPipeline完成任务以后会自动删除自己

说明

io.netty.channel.ChannelInitializer是一个特殊的ChannelInboundHandler。它的主要作用是向 Channel对应的ChannelPipeline中增加ChannelHandler。执行完ChannelInitializer的initChannel(C ch)函数以后,ChannelInitializer就会从ChannelPipeline自动删除自己,防止重复进入。

一般是通过Bootstrap.handler(ChannelHandler) 、ServerBootstrap.childHandler(ChannelHandler)的方式分别在客户端、服务端中将ChannelInitializer这个ChannelHandler增加到ChannelPipeline中。

示例

思路

我们来验证下ChannelInitializer是否会被自动删除。我们在ChannelInitializer的initChannel(C ch)函数末尾打印出来当前ChannelPipeline中已经添加的ChannelHandler名称;在Channel连接成功以后,再打印出来当前ChannelPipeline中已经添加的ChannelHandler名称,两者对照下,就能看出来是否被自动删除了。

代码片段

package com.thb.power.terminal;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import com.thb.power.packet.register.RegisterRequestPacket;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * 主函数
 * @author thb
 *
 */
public class Terminal {
	// 要连接的服务端的host 
	static final String HOST = System.getProperty("host", "127.0.0.1"); 
	// 要连接的服务端的端口号 
	static final int PORT = Integer.parseInt(System.getProperty("port", "22335"));

	public static void main(String[] args) throws Exception {
		// 配置客户端
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap();
			b.group(group)
			 .channel(NioSocketChannel.class)
			 .option(ChannelOption.TCP_NODELAY, true)
			 .handler(new TerminalInitializer());
			
			// 启动客户端
			Channel ch = b.connect(HOST, PORT).sync().channel();		
			
			// 查看ChannelPipeline添加的ChannelHandler名称
			System.out.println("after channel connected:");
			for (String name : ch.pipeline().names()) {
				System.out.println("handler name: " + name);
			} 
			
			ChannelFuture lastWriteFuture = null;
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			System.out.println("please input(register):");
			for (;;) {
				String line = in.readLine();
				if (line == null) {
					break;
				}				

				// 如果用户输入register,表示命令客户端发送注册请求给服务器
				if (line.toLowerCase().equals("register")) {
					RegisterRequestPacket registerRequest = new RegisterRequestPacket();
					// 返回的ByteBuf存放着注册请求的数据
					ByteBuf buf = registerRequest.build(ch);
					
					lastWriteFuture = ch.writeAndFlush(buf);						
				}
			}
			
			if (lastWriteFuture != null) {
				lastWriteFuture.sync();
			}
		} finally {
			// 关闭event loop以便终止所有的线程
			group.shutdownGracefully();
		}

	}

}


// ChannelInitializer的子类
package com.thb.power.terminal;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class TerminalInitializer extends ChannelInitializer<SocketChannel> {

	 @Override
	 public void initChannel(SocketChannel ch) throws Exception {
		 ChannelPipeline p = ch.pipeline();
		 p.addLast(new LoggingHandler(LogLevel.INFO));
		 
		 // 查看ChannelPipeline添加的ChannelHandler名称
		 System.out.println("in initChannel(SocketChannel ch) method of TerminalInitializer:");
		 for (String name : ch.pipeline().names()) {
			 System.out.println("handler name: " + name);
		 } 
	 }
}

运行输出

从上面输出可以看出,ChannelInitializer开始被添加到ChannelPipeline中,后来又被自动删除了。

相关推荐
天天扭码34 分钟前
五天SpringCloud计划——DAY1之mybatis-plus的使用
java·spring cloud·mybatis
程序猿小柒40 分钟前
leetcode hot100【LeetCode 4.寻找两个正序数组的中位数】java实现
java·算法·leetcode
不爱学习的YY酱1 小时前
【操作系统不挂科】<CPU调度(13)>选择题(带答案与解析)
java·linux·前端·算法·操作系统
丁总学Java1 小时前
Maven项目打包,com.sun.tools.javac.processing
java·maven
kikyo哎哟喂2 小时前
Java 代理模式详解
java·开发语言·代理模式
duration~2 小时前
SpringAOP模拟实现
java·开发语言
小码ssim2 小时前
IDEA使用tips(LTS✍)
java·ide·intellij-idea
潜洋2 小时前
Spring Boot教程之五:在 IntelliJ IDEA 中运行第一个 Spring Boot 应用程序
java·spring boot·后端
暮志未晚Webgl3 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
小叶lr3 小时前
idea 配置 leetcode插件 代码模版
java·leetcode·intellij-idea