netty源码探索(二)

0. ctx.fire*** 或者 ctx.read write
都是基于当前的ctx查找下一个outbound和inbound不会中从headcontext或者tailcontext开始
如果需要从头开始调用ctx.pipeline()
注意在编写outbound和inbound handler不要忘记调用ctx函数不然链路会断掉
1. outbound和inbound操作
ChannelOutboundHandler
+void bind(ctx, localAddress, promise)
+void connect(ctx, remoteaddr, localaddr, promose)
+void disconnect(ctx, promise)
+void deregister(ctx, promise)
+void close(ctx, promise)
+void write(ctx, msg, promise)
+void flush(ctx)
+void read(ctx)
ChannelInboundHandler
+void channelRegistered(ChannelHandlerContext ctx)
+void channelUnregistered(ChannelHandlerContext ctx)
+void channelActive(ChannelHandlerContext ctx)
+void channelInactive(ChannelHandlerContext ctx)
+void channelRead(ChannelHandlerContext ctx, Object msg)
+void channelReadComplete(ChannelHandlerContext ctx)
+void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
+void channelWritabilityChanged(ChannelHandlerContext ctx)
+void userEventTriggered(ChannelHandlerContext ctx, Object evt)

2. close
如果是IO线程调用close,最终调用unsafe.close(promise);
1. 设置outboundBuffer为null
2. javaChannel().close();
3. channel中的closeFuture设置为closed
4. 之前写入没有被flush在outboundBuffer的数据会被丢弃,future被设置为done,notsuccess
4. fireChannelInactiveAndDeregister invokeLater 
	注册一个doDeregister任务,里面finnaly会调用
	pipeline.fireChannelInactive();
	和
	pipeline.fireChannelUnregistered();

close后writeAndFlush都不会发送
多次close,第二次后因为closeFuture.isDone()所以不会有作用,但是piple的处理链还是会打印在
unsafeclose中不会有实际作用

2. exceptionCaught出现异常
exceptionCaught中如果抛出异常(Throwable error)会打印警告不会出现死循环


3. read的含义
channelActive中会执行一次readIfIsAutoRead会出发一次pipeline.read->tailcontext->.....->headcontext.read
ctx.read()主要用于设置selectionKey.interestOps(interestOps | readInterestOp);
跟processSelectedKey中出发的unsafe.read()完全不同,unsafe.read()会触发fireChannelRead


4. 异常捕获机制
notifyHandlerException 
{
	if (inExceptionCaught(cause)) {
        if (logger.isWarnEnabled()) {
            logger.warn(
                    "An exception was thrown by a user handler " +
                            "while handling an exceptionCaught event", cause);
        }
        return;
    }

    invokeExceptionCaught(cause); 调用发生异常所在的ctx开始调用(本ctx也会调用一次)
}
notifyHandlerException如下:
ctx.read() 
ctx.flush()
fireChannelRegistered
fireChannelUnregistered
fireChannelActive
fireChannelInactive
fireUserEventTriggered
fireChannelRead
fireChannelReadComplete
fireChannelWritabilityChanged


notifyOutboundHandlerException
{
 PromiseNotificationUtil.tryFailure(promise, cause, promise instanceof VoidChannelPromise ? null : logger);
 {
	if (!p.tryFailure(cause) && logger != null) {	// 设置future为fail,调用listener
        Throwable err = p.cause();
        if (err == null) {
            logger.warn("Failed to mark a promise as failure because it has succeeded already: {}", p, cause);
        } else {
            logger.warn(
                    "Failed to mark a promise as failure because it has failed already: {}, unnotified cause: {}",
                    p, ThrowableUtil.stackTraceToString(err), cause);
        }
    }
}
notifyOutboundHandlerException调用后设置相应的promise状态以及listener直接返回
notifyOutboundHandlerException
ctx.write(msg, promise)
ctx.bind
ctx.connect
ctx.disconnect
ctx.close
ctx.deregister

5. write只是将数据放入到outboundBuffer中,flush会调用ch.write(nioBuffer)将outboundBuffer的数据发送出去

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值