SimpleChannelInboundHandler 源码笔记
io.netty.util.internal.TypeParameterMatcher
定义: 类型参数匹配器 功能: 用于判断 SimpleChannelInboundHandler<?> 中传入参数是否是该handler要处理的 message
io.netty.channel.SimpleChannelInboundHandler
public abstract class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter { private final TypeParameterMatcher matcher; private final boolean autoRelease; protected SimpleChannelInboundHandler() { this(true); } protected SimpleChannelInboundHandler(boolean autoRelease) { this.matcher = TypeParameterMatcher.find(this, SimpleChannelInboundHandler.class, "I"); this.autoRelease = autoRelease; } protected SimpleChannelInboundHandler(Class<? extends I> inboundMessageType) { this(inboundMessageType, true); } // 获取iboundMEssageType参数的 类型 matcher, 自动release 为 true, 这是于ChannelInboundHandler 的不同点,后者需要手动释放 protected SimpleChannelInboundHandler(Class<? extends I> inboundMessageType, boolean autoRelease) { this.matcher = TypeParameterMatcher.get(inboundMessageType); this.autoRelease = autoRelease; } public boolean acceptInboundMessage(Object msg) throws Exception { return this.matcher.match(msg); } public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean release = true; try { // 如果接收到的参数是匹配类型,则处理 if (this.acceptInboundMessage(msg)) { this.channelRead0(ctx, msg); } else { // 不匹配交给下一个handler 处理 release = false; ctx.fireChannelRead(msg); } } finally { if (this.autoRelease && release) { // 引用计数减一 ReferenceCountUtil.release(msg); } } } // 由子类实现 protected abstract void channelRead0(ChannelHandlerContext var1, I var2) throws Exception; }
事例:
/** * @Author Mario * @Date 2022-03-24 19:42 * @Version : * @Description : 专门处理LoginRequestPacket 对象的请求,处理不了的直接传给下一个handler, 避免过多的if/else 处理不同的请求 */ public class LoginRequestHandler extends SimpleChannelInboundHandler<LoginRequestPacket> { @Override protected void channelRead0(ChannelHandlerContext ctx, LoginRequestPacket packet) throws Exception { LoginResponsePacket loginResponsePacket = new LoginResponsePacket(); loginResponsePacket.setVersion(packet.getVersion()); if (valid(packet)) { // 校验成功 loginResponsePacket.setSuccess(true); System.out.println(new Date() + ": 登录成功"); } else { // 失败 loginResponsePacket.setReason("账号密码不正确"); loginResponsePacket.setSuccess(false); System.out.println(new Date() + ": 登录失败"); } // 登录响应 // ByteBuf out = PacketCodeC.INSTANCE.encode(ctx.alloc(), loginResponsePacket); ctx.channel().writeAndFlush(loginResponsePacket); } }
上一篇:
IDEA上Java项目控制台中文乱码