久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

handler的執行順序是怎么樣的

202次閱讀
沒有評論

共計 2426 個字符,預計需要花費 7 分鐘才能閱讀完成。

本篇內容主要講解“handler 的執行順序是怎么樣的”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“handler 的執行順序是怎么樣的”吧!

為了說明這個問題我們增加了 2 個 encoder,分別是 MavlinkMsg2BytesEncoder 和 FixLengthEncoder,作用分別是將一個協議對象轉化為 byte 數組,另一個是為了客戶端解析的方便,增加了一個定長的設置。
還是按照老方法,設置斷點,然后查看其調用順序。

NettyServerHandler.messageReceived 是我們接收下行消息的終點,我們直接在這里來執行消息的返回。

首先進入 NioSocketChannel.write 方法,下面是代碼

@Override
  public ChannelFuture write(Object msg) {
  return pipeline.write(msg);
  }

write 方法定義在 AbstractChannel 當中,是 netty 當中所有的 channel 類的祖先。

在這個方法當中,開始執行依次執行 pipeline 當中的各個 handler

下面是 DefaultChannelPipeline.write 方法

@Override
  public ChannelFuture write(Object msg) {
  return tail.write(msg);
  }

如果沒有記錯的話,下行的過程當中,是從 head.fireChannelRead 開始的,而在上行的過程當中,是從 tail 開始的,而實際上,head 和 tail 是 pipeline 在初始化的時候默認生成的雙向鏈表的頭尾節點,他們并不完成任何實際工作。這里從 tail 開是上行的過程,應該說是非常符合邏輯的。

下一步我們看 DefaultChannelHandlerContext.write 方法

@Override
  public ChannelFuture write(Object msg, ChannelPromise promise) {
  DefaultChannelHandlerContext next = findContextOutbound(MASK_WRITE);
  next.invoker.invokeWrite(next, msg, promise);
  return promise;
  }

這里也是之前我們分析過的代碼,查找雙向鏈表當中 prev 節點。

之后是 ChannelHandlerInvokerUtil.invokeWriteNow 方法,

public static void invokeWriteNow(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
  try {
  ctx.handler().write(ctx, msg, promise);
  } catch (Throwable t) {
  notifyOutboundHandlerException(t, promise);
  }
  }

再然后是 MessageToByteEncoder.write 方法,

public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
  ByteBuf buf = null;
  try {
  if (acceptOutboundMessage(msg)) {
  @SuppressWarnings(unchecked)
  I cast = (I) msg;
  if (preferDirect) {
  buf = ctx.alloc().ioBuffer();
  } else {
  buf = ctx.alloc().heapBuffer();
  }
  try {
  encode(ctx, cast, buf);
  } finally {
  ReferenceCountUtil.release(cast);
  }

  if (buf.isReadable()) {
  ctx.write(buf, promise);
  } else {
  buf.release();
  ctx.write(Unpooled.EMPTY_BUFFER, promise);
  }
  buf = null;
  } else {
  ctx.write(msg, promise);
  }
  } catch (EncoderException e) {
  throw e;
  } catch (Throwable e) {
  throw new EncoderException(e);
  } finally {
  if (buf != null) {
  buf.release();
  }
  }
  }

這里分配一個動態緩沖區,然后調用 encoder 方法。

  if (preferDirect) {
  buf = ctx.alloc().ioBuffer();
  } else {
  buf = ctx.alloc().heapBuffer();
  }

請注意這段代碼,這里的概念是指,當前緩沖區的分配是從系統 io 當中來分配,還是從 jvm 的堆當中來分配,2 種方式各有利弊,將來我們會專門介紹這個問題。

在最后就是我們的 encode 方法了。

protected void encode(ChannelHandlerContext ctx, MAVLinkMessage msg, ByteBuf out) throws Exception {
     MAVLinkPacket packet = msg.pack();
     byte[] buf = packet.encodePacket();
     out.writeBytes(buf);
   }

而后續的 encoder 的調用過程基本跟前面大同小異。這里就不再贅述了。

到此,相信大家對“handler 的執行順序是怎么樣的”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計2426字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 松溪县| 彰化市| 北辰区| 新干县| 云阳县| 揭东县| 广水市| 克什克腾旗| 政和县| 固安县| 潼关县| 获嘉县| 玉树县| 桐柏县| 古浪县| 五莲县| 威信县| 徐州市| 博白县| 景洪市| 新民市| 乡城县| 周至县| 同德县| 凤城市| 家居| 江都市| 湘潭市| 静宁县| 贵州省| 蓬安县| 沙洋县| 宜丰县| 龙泉市| 佳木斯市| 临猗县| 随州市| 津南区| 安岳县| 嘉善县| 乐亭县|