说明
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);
}
}
}
运行输出
文章来源:https://www.toymoban.com/news/detail-631105.html
从上面输出可以看出,ChannelInitializer开始被添加到ChannelPipeline中,后来又被自动删除了。文章来源地址https://www.toymoban.com/news/detail-631105.html
到了这里,关于Netty:ChannelInitializer添加到ChannelPipeline完成任务以后会自动删除自己的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!