<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                雖然我們一直把解碼器和編碼器作為不同的實體來討論,但你有時可能會發現把入站和出站的數據和信息轉換都放在同一個類中更實用。Netty的抽象編解碼器類就是用于這個目的,他們把一些成對的解碼器和編碼器組合在一起,以此來提供對于字節和消息都相同的操作。(這些類實現了 ChannelInboundHandler 和 ChannelOutboundHandler )。 您可能想知道是否有時候使用單獨的解碼器和編碼器會比使用這些組合類要好,最簡單的答案是,緊密耦合的兩個函數減少了他們的可重用性,但是把他們分開實現就會更容易擴展。當我們研究抽象編解碼器類時,我們也會拿它和對應的獨立的解碼器和編碼器做對比。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Abstract%20Codec%20classes.md#bytetomessagecodec)ByteToMessageCodec 我們需要解碼字節到消息,也許是一個 POJO,然后轉回來。ByteToMessageCodec 將為我們處理這個問題,因為它結合了ByteToMessageDecoder 和 MessageToByteDecoder。表7.5中列出的重要方法。 Table 7.5 ByteToMessageCodec API | 方法名稱 | 描述 | | --- | --- | | decode | This method is called as long as bytes are available to be consumed. It converts the inbound ByteBuf to the specified message format and forwards them to the next ChannelInboundHandler in the pipeline. | | decodeLast | The default implementation of this method delegates to decode(). It is called only be called once, when the Channel goes inactive. For special handling it can be oerridden. | | encode | This method is called for each message to be written through the ChannelPipeline. The encoded messages are contained in a ByteBuf which | 什么會是一個好的 ByteToMessageCodec 用例?任何一個請求/響應協議都可能是,例如 SMTP。編解碼器將讀取入站字節并解碼到一個自定義的消息類型 SmtpRequest 。當接收到一個 SmtpResponse 會產生,用于編碼為字節進行傳輸。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Abstract%20Codec%20classes.md#messagetomessagecodec)MessageToMessageCodec 7.3.2節中我們看到的一個例子使用 MessageToMessageEncoder 從一個消息格式轉換到另一個地方。現在讓我們看看 MessageToMessageCodec 是如何處理 單個類 的往返。 在進入細節之前,讓我們看看表7.6中的重要方法。 Table 7.6 Methods of MessageToMessageCodec | 方法名稱 | 描述 | | --- | --- | | decode | This method is called with the inbound messages of the codec and decodes them to messages. Those messages are forwarded to the next ChannelInboundHandler in the ChannelPipeline | | decodeLast | Default implementation delegates to decode().decodeLast will only be called one time, which is when the Channel goes inactive. If you need special handling here you may override decodeLast() to implement it. | | encode | The encode method is called for each outbound message to be moved through the ChannelPipeline. The encoded messages are forwarded to the next ChannelOutboundHandler in the pipeline | MessageToMessageCodec 是一個參數化的類,定義如下: ~~~ public abstract class MessageToMessageCodec<INBOUND,OUTBOUND> ~~~ 上面所示的完整簽名的方法都是這樣的 ~~~ protected abstract void encode(ChannelHandlerContext ctx, OUTBOUND msg, List<Object> out) protected abstract void decode(ChannelHandlerContext ctx, INBOUND msg, List<Object> out) ~~~ encode() 處理出站消息類型 OUTBOUND 到 INBOUND,而 decode() 則相反。我們在哪里可能使用這樣的編解碼器? 在現實中,這是一個相當常見的用例,往往涉及兩個來回轉換的數據消息傳遞API 。這是常有的事,當我們不得不與遺留或專有的消息格式進行互操作。 如清單7.7所示這樣的可能性。在這個例子中,WebSocketConvertHandler 是一個靜態嵌套類,繼承了參數為 WebSocketFrame(類型為 INBOUND)和 WebSocketFrame(類型為 OUTBOUND)的 MessageToMessageCode Listing 7.7 MessageToMessageCodec ~~~ public class WebSocketConvertHandler extends MessageToMessageCodec<WebSocketFrame, WebSocketConvertHandler.WebSocketFrame> { //1 public static final WebSocketConvertHandler INSTANCE = new WebSocketConvertHandler(); @Override protected void encode(ChannelHandlerContext ctx, WebSocketFrame msg, List<Object> out) throws Exception { ByteBuf payload = msg.getData().duplicate().retain(); switch (msg.getType()) { //2 case BINARY: out.add(new BinaryWebSocketFrame(payload)); break; case TEXT: out.add(new TextWebSocketFrame(payload)); break; case CLOSE: out.add(new CloseWebSocketFrame(true, 0, payload)); break; case CONTINUATION: out.add(new ContinuationWebSocketFrame(payload)); break; case PONG: out.add(new PongWebSocketFrame(payload)); break; case PING: out.add(new PingWebSocketFrame(payload)); break; default: throw new IllegalStateException("Unsupported websocket msg " + msg); } } @Override protected void decode(ChannelHandlerContext ctx, io.netty.handler.codec.http.websocketx.WebSocketFrame msg, List<Object> out) throws Exception { if (msg instanceof BinaryWebSocketFrame) { //3 out.add(new WebSocketFrame(WebSocketFrame.FrameType.BINARY, msg.content().copy())); } else if (msg instanceof CloseWebSocketFrame) { out.add(new WebSocketFrame(WebSocketFrame.FrameType.CLOSE, msg.content().copy())); } else if (msg instanceof PingWebSocketFrame) { out.add(new WebSocketFrame(WebSocketFrame.FrameType.PING, msg.content().copy())); } else if (msg instanceof PongWebSocketFrame) { out.add(new WebSocketFrame(WebSocketFrame.FrameType.PONG, msg.content().copy())); } else if (msg instanceof TextWebSocketFrame) { out.add(new WebSocketFrame(WebSocketFrame.FrameType.TEXT, msg.content().copy())); } else if (msg instanceof ContinuationWebSocketFrame) { out.add(new WebSocketFrame(WebSocketFrame.FrameType.CONTINUATION, msg.content().copy())); } else { throw new IllegalStateException("Unsupported websocket msg " + msg); } } public static final class WebSocketFrame { //4 public enum FrameType { //5 BINARY, CLOSE, PING, PONG, TEXT, CONTINUATION } private final FrameType type; private final ByteBuf data; public WebSocketFrame(FrameType type, ByteBuf data) { this.type = type; this.data = data; } public FrameType getType() { return type; } public ByteBuf getData() { return data; } } } ~~~ 1. 編碼 WebSocketFrame 消息轉為 WebSocketFrame 消息 2. 檢測 WebSocketFrame 的 FrameType 類型,并且創建一個新的響應的 FrameType 類型的 WebSocketFrame 3. 通過 instanceof 來檢測正確的 FrameType 4. 自定義消息類型 WebSocketFrame 5. 枚舉類明確了 WebSocketFrame 的類型 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Abstract%20Codec%20classes.md#combinedchannelduplexhandler)CombinedChannelDuplexHandler 如前所述,結合解碼器和編碼器在一起可能會犧牲可重用性。為了避免這種方式,并且部署一個解碼器和編碼器到 ChannelPipeline 作為邏輯單元而不失便利性。 關鍵是下面的類: ~~~ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler,O extends ChannelOutboundHandler> ~~~ 這個類是擴展 ChannelInboundHandler 和 ChannelOutboundHandler 參數化的類型。這提供了一個容器,單獨的解碼器和編碼器類合作而無需直接擴展抽象的編解碼器類。我們將在下面的例子說明這一點。首先查看 ByteToCharDecoder ,如清單7.8所示。 Listing 7.8 ByteToCharDecoder ~~~ public class ByteToCharDecoder extends ByteToMessageDecoder { //1 @Override public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() >= 2) { //2 out.add(in.readChar()); } } } ~~~ 1. 繼承 ByteToMessageDecoder 2. 寫 char 到 MessageBuf decode() 方法從輸入數據中提取兩個字節,并將它們作為一個 char 寫入 List 。(注意,實現擴展 ByteToMessageDecoder 因為它從 ByteBuf 讀取字符。) 現在看一下清單7.9中,把字符轉換為字節的編碼器。 Listing 7.9 CharToByteEncoder ~~~ public class CharToByteEncoder extends MessageToByteEncoder<Character> { //1 @Override public void encode(ChannelHandlerContext ctx, Character msg, ByteBuf out) throws Exception { out.writeChar(msg); //2 } } ~~~ 1. 繼承 MessageToByteEncoder 2. 寫 char 到 ByteBuf 這個實現繼承自 MessageToByteEncoder 因為他需要編碼 char 消息 到 ByteBuf。這將直接將字符串寫為 ByteBuf。 現在我們有編碼器和解碼器,將他們組成一個編解碼器。見下面的 CombinedChannelDuplexHandler. Listing 7.10 CombinedByteCharCodec ~~~ public class CombinedByteCharCodec extends CombinedChannelDuplexHandler<ByteToCharDecoder, CharToByteEncoder> { public CombinedByteCharCodec() { super(new ByteToCharDecoder(), new CharToByteEncoder()); } } ~~~ 1. CombinedByteCharCodec 的參數是解碼器和編碼器的實現用于處理進站字節和出站消息 2. 傳遞 ByteToCharDecoder 和 CharToByteEncoder 實例到 super 構造函數來委托調用使他們結合起來。 正如你所看到的,它可能是用上述方式來使程序更簡單、更靈活,而不是使用一個以上的編解碼器類。它也可以歸結到你個人喜好或風格。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看