childhandler 和 handler 区别
在 Netty 中,Bootstrap 和 ServerBootstrap 是用于配置客户端和服务端网络应用的核心类,它们的 handler() 和 childHandler() 方法用于设置不同的处理器,主要区别如下:
1. 适用场景
| 方法 | 适用对象 | 作用目标 Channel 类型 |
|---|---|---|
handler() |
客户端 Bootstrap |
用于设置 父 Channel 的处理器(如 NioSocketChannel) |
服务端 ServerBootstrap |
用于设置 服务端监听 Channel 的处理器(如 NioServerSocketChannel) |
|
childHandler() |
仅服务端 ServerBootstrap |
用于设置 新接受的客户端连接 Channel 的处理器(如 NioSocketChannel) |
2. 核心区别
(1) handler()
-
客户端(
Bootstrap):
用于配置客户端自身的处理器(如编解码器、日志、业务逻辑等)。Bootstrap b = new Bootstrap(); b.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline().addLast(new MyClientHandler()); } }); -
服务端(
ServerBootstrap):
用于配置服务端监听端口的处理器(如监控服务器状态、记录连接数等),一般不处理具体业务。ServerBootstrap b = new ServerBootstrap(); b.handler(new LoggingHandler(LogLevel.INFO)); // 监听端口日志
(2) childHandler()
-
仅服务端(
ServerBootstrap):
用于配置每个新接受的客户端连接的处理器(如编解码器、身份验证、业务逻辑等)。ServerBootstrap b = new ServerBootstrap(); b.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast(new StringDecoder()) .addLast(new StringEncoder()) .addLast(new MyServerHandler()); } });
3. 执行流程对比
NioSocketChannelNioServerSocketChannel服务端客户端NioSocketChannelNioServerSocketChannel服务端客户端发起连接监听端口(handler()生效)创建新连接(childHandler()生效)通信
4. 关键注意事项
-
客户端没有
childHandler
因为客户端只需管理自己的单一连接,直接使用handler()。 -
服务端必须区分两者
-
handler()影响服务端自身的监听行为(如记录连接事件)。 -
childHandler()影响每个客户端连接的处理逻辑(如业务处理)。
-
-
典型配置示例
ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler()) // 服务端自身日志 .childHandler(new ChannelInitializer<SocketChannel>() { // 客户端连接处理 @Override protected void initChannel(SocketChannel ch) { // 添加处理器... } });
5. 常见问题
-
混淆使用:在服务端误将业务处理器加到
handler()而非childHandler(),导致无法处理客户端数据。 -
性能影响:
handler()中的处理器会共享于所有客户端连接,需确保线程安全(如添加@Sharable注解)。
总结
-
handler():配置“父级”Channel(客户端自身/服务端监听端口)。 -
childHandler():配置服务端接受的“子级”客户端连接。 -
记忆技巧:服务端像“父亲”,用
handler()管自己,用childHandler()管“孩子”(客户端连接)。
浙公网安备 33010602011771号