欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Netty編碼器和解碼器

 更新時間:2021年06月07日 10:34:06   作者:_tommy  
很多小伙伴對Netty編解碼器這方面不是很了解,今天這篇文章給大家詳細介紹了Netty編碼器和解碼器的相關知識,需要的朋友可以參考下

一、java的編解碼

1.編碼(Encode)稱為序列化, 它將對象序列化為字節(jié)數組,用于網絡傳輸、數據持久化或者其它 用途。

2.解碼(Decode)稱為反序列化,它把從網絡、磁盤等讀取的字節(jié)數組還原成原始對象(通常是原 始對象的拷貝),以方便后續(xù)的業(yè)務邏輯操作。

image-20210605230045944

java序列化對象只需要實現java.io.Serializable接口并生成序列化ID,這個類就能夠通過 java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

java序列化對象只需要實現java.io.Serializable接口并生成序列化ID,這個類就能夠通過 java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

Java序列化目的:1.網絡傳輸。2.對象持久化。

Java序列化缺點:1.無法跨語言。 2.序列化后碼流太大。3.序列化性能太低。

Java序列化僅僅是Java編解碼技術的一種,由于它的種種缺陷,衍生出了多種編解碼技術和框 架,這些編解碼框架實現消息的高效序列化。

二、Netty編解碼器

概念:在網絡應用中需要實現某種編解碼器,將原始字節(jié)數據與自定義的消息對象進行互相轉換。網絡中都是以字節(jié)碼的數據形式來傳輸數據的,服務器編碼數據后發(fā)送到客戶端,客戶端需要對數據進行解碼。

對于Netty而言,編解碼器由兩部分組成:編碼器、解碼器

  • 解碼器:負責將消息從字節(jié)或其他序列形式轉成指定的消息對象。
  • 編碼器:將消息對象轉成字節(jié)或其他序列形式在網絡上傳輸。

Netty 的編(解)碼器實現了 ChannelHandlerAdapter,也是一種特殊的 ChannelHandler,所 以依賴于 ChannelPipeline,可以將多個編(解)碼器鏈接在一起,以實現復雜的轉換邏輯。

Netty里面的編解碼: 解碼器:負責處理“入站 InboundHandler”數據。 編碼器:負責“出站 OutboundHandler” 數據。

入棧解碼,出棧編碼:

2.1 解碼器(Decoder)

解碼器負責 解碼“入站”數據從一種格式到另一種格式,解碼器處理入站數據是抽象 ChannelInboundHandler的實現。需要將解碼器放在ChannelPipeline中。對于解碼器,Netty中主要提供了抽象基類ByteToMessageDecoder和MessageToMessageDecoder。

image-20210605231024070

抽象解碼器

ByteToMessageDecoder: 用于將字節(jié)轉為消息,需要檢查緩沖區(qū)是否有足夠的字節(jié)

ReplayingDecoder: 繼承ByteToMessageDecoder,不需要檢查緩沖區(qū)是否有足夠的字節(jié),但 是 ReplayingDecoder速度略慢于ByteToMessageDecoder,同時不是所有的ByteBuf都支持。 項目復雜性高則使用ReplayingDecoder,否則使用ByteToMessageDecoder

MessageToMessageDecoder: 用于從一種消息解碼為另外一種消息(例如POJO到POJO)

核心方法

decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)

2.2 代碼實現

 MessageDecoder

package com.my.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息解碼器
 */
public class MessageDecoder extends MessageToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("正在進行消息解碼....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個handler
    }
}

NettyServerHandler

nettyServerHandler 實現ChannelInboundHandler, 重新若干方法。

通道讀取方法:

/**
     * 通道讀取事件
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客戶端發(fā)送過來的消息:" + msg);
    }

服務端在接收客戶端的消息時,首先會經過MessageDecoder編碼器,將字節(jié)變?yōu)樽址?,因此,在此處可直接輸出?/p>

NettyServer

serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                .childHandler(new ChannelInitializer<SocketChannel>() { 
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //添加解碼器
                        ch.pipeline().addLast("messageDecoder", new MessageDecoder());
                        //向pipeline中添加自定義業(yè)務處理handler
                        ch.pipeline().addLast(new NettyServerHandler());
                    }
                });

在pipeline中添加解碼器

2.3 編碼器(Encoder)

與ByteToMessageDecoder和MessageToMessageDecoder相對應,Netty提供了對應的編碼器 實現MessageToByteEncoder和MessageToMessageEncoder,二者都實現 ChannelOutboundHandler接口。

image-20210605232231876

抽象編碼器

MessageToByteEncoder: 將消息轉化成字節(jié)MessageToMessageEncoder: 用于從一種消息編碼為另外一種消息(例如POJO到POJO)

核心方法:

encode(ChannelHandlerContext ctx, String msg, List<Object> out)

2.4 代碼實現

MessageEncoder

package com.my.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息的編碼器
 */
public class MessageEncoder extends MessageToMessageEncoder {
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("消息正在進行編碼....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }
}

NettyClientHandler

/**
     * 通道就緒事件
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ChannelFuture future = ctx.writeAndFlush("你好呀.我是Netty客戶端");
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("數據發(fā)送成功!");
                } else {
                    System.out.println("數據發(fā)送失敗!");
                }
            }
        });
    }

    /**
     * 通道讀就緒事件
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服務端發(fā)送的消息:" + msg);
    }

當客戶端通道準備就緒時,會向服務端發(fā)送 “你好呀.我是Netty客戶端”,由于出棧是逆序的,因此,直接傳入字符串,當出棧時,會經過編碼器(在nettyclient中添加的)

NettyClient

bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() { 
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //添加解碼器
                        ch.pipeline().addLast("messageDecoder", new MessageDecoder());
                        //添加編碼器
                        ch.pipeline().addLast("messageEncoder", new MessageEncoder());                  
                        //向pipeline中添加自定義業(yè)務處理handler
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });

同時,在NettyServerHandler 中也添加相同的編解碼器。

因為是雙向通信,因此,在服務端和客戶端的pipeline中均需要添加編解碼器。

2.5 測試結果

服務端打印:

image-20210605233932707

客戶端打?。?/p>

image-20210605233943017

三、編碼解碼器Codec

編碼解碼器:

同時具有編碼與解碼功能,特點同時實現了ChannelInboundHandler和 ChannelOutboundHandler接口,因此在數據輸入和輸出時都能進行處理。

image-20210605234135527

Netty提供提供了一個ChannelDuplexHandler適配器類,編碼解碼器的抽象基類

ByteToMessageCodec ,MessageToMessageCodec都繼承與此類

3.1 代碼實現:

package com.my.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息編解碼器
 */
public class MessageCodec extends MessageToMessageCodec {
    /**
     * 編碼
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("消息正在進行編碼....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }

    /**
     * 解碼
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("正在進行消息解碼....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個handler
    }
}

NettyServer、NettyClient

在NettyServer和NettyClient中添加

ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定義業(yè)務處理handler
ch.pipeline().addLast(new NettyServerHandler());

eBuf = (ByteBuf) msg;
out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個handler
}
}

ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定義業(yè)務處理handler
ch.pipeline().addLast(new NettyServerHandler());

測試結果與1.2.5測試結果一致

到此這篇關于詳解Netty編碼器和解碼器的文章就介紹到這了,更多相關Netty編解碼器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring Boot實戰(zhàn)之靜態(tài)資源處理

    Spring Boot實戰(zhàn)之靜態(tài)資源處理

    這篇文章主要介紹了Spring Boot實戰(zhàn)之靜態(tài)資源處理,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 詳解在Java的Struts2框架中配置Action的方法

    詳解在Java的Struts2框架中配置Action的方法

    這篇文章主要介紹了詳解在Java的Struts2框架中配置Action的方法,講解了包括struts.xml中的action配置及基于注解方式Action配置的兩個方式,需要的朋友可以參考下
    2016-03-03
  • 基于Springboot的高校社團管理系統(tǒng)的設計與實現

    基于Springboot的高校社團管理系統(tǒng)的設計與實現

    本文將基于Springboot+Mybatis開發(fā)實現一個高校社團管理系統(tǒng),系統(tǒng)包含三個角色:管理員、團長、會員。文中采用的技術有Springboot、Mybatis、Jquery、AjAX、JSP等,感興趣的可以了解一下
    2022-07-07
  • Java實現UDP多線程在線咨詢

    Java實現UDP多線程在線咨詢

    這篇文章主要為大家詳細介紹了Java實現UDP多線程在線咨詢,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Driver問題

    徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Dr

    這篇文章給大家介紹了如如何徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Driver問題,文中有詳細的解決思路以及解決方法,需要的朋友可以參考下
    2023-11-11
  • Java中switch判斷語句典型使用實例

    Java中switch判斷語句典型使用實例

    這篇文章主要介紹了Java中switch判斷語句典型使用實例,本文直接給出代碼實例,在忘記switch語法時特別有用,復制修改即可使用,需要的朋友可以參考下
    2015-06-06
  • Groovy編程入門攻略

    Groovy編程入門攻略

    這篇文章主要介紹了Groovy編程入門攻略,Groovy是一種同樣使用Java虛擬機的動態(tài)語言,需要的朋友可以參考下
    2015-07-07
  • Spring Gateway處理微服務的路由轉發(fā)機制

    Spring Gateway處理微服務的路由轉發(fā)機制

    我們詳細地介紹了Spring Gateway,這個基于Spring 5、Spring Boot 2和Project Reactor的API網關,通過這篇文章,我們可以清晰地看到Spring Gateway的工作原理,以及它的強大之處,感興趣的朋友一起看看吧
    2024-08-08
  • 字節(jié)二面SpringBoot可以同時處理多少請求

    字節(jié)二面SpringBoot可以同時處理多少請求

    這篇文章主要為大家介紹了字節(jié)二面之SpringBoot可以同時處理多少請求面試分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • JAVA三種異常處理機制的具體使用

    JAVA三種異常處理機制的具體使用

    異常是程序在編譯或執(zhí)行的過程中可能出現的問題,本文主要介紹了JAVA三種異常處理機制的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06

最新評論