亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用Netty進(jìn)行編解碼的操作過(guò)程詳解

 更新時(shí)間:2019年07月15日 09:51:08   作者:正號(hào)先生  
這篇文章主要介紹了使用Netty進(jìn)行編解碼的操作過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

前言

何為編解碼,通俗的來(lái)說(shuō),我們需要將一串文本信息從A發(fā)送到B并且將這段文本進(jìn)行加工處理,如:A將信息文本信息編碼為2進(jìn)制信息進(jìn)行傳輸。B接受到的消息是一串2進(jìn)制信息,需要將其解碼為文本信息才能正常進(jìn)行處理。

上章我們介紹的Netty如何解決拆包和粘包問(wèn)題,就是運(yùn)用了解碼的這一功能。

java默認(rèn)的序列化機(jī)制

使用Netty大多是java程序猿,我們基于一切都是對(duì)象的原則,經(jīng)常會(huì)將對(duì)象進(jìn)行網(wǎng)絡(luò)傳輸,那么對(duì)于序列化操作肯定大家都是非常熟悉的。

一個(gè)對(duì)象是不能直接進(jìn)行網(wǎng)絡(luò)I/O傳輸?shù)?,jdk默認(rèn)是將對(duì)象轉(zhuǎn)換為可存儲(chǔ)的字節(jié)數(shù)組來(lái)進(jìn)行網(wǎng)絡(luò)操作?;贘DK默認(rèn)的序列化機(jī)制可以避免操作底層的字節(jié)數(shù)組,從而提升開發(fā)效率。

jdk默認(rèn)的序列化機(jī)制雖然能給程序猿帶來(lái)極大的方便,但是它也帶來(lái)了許多問(wèn)題:

  • 無(wú)法跨語(yǔ)言。
  • 序列化后的碼流太大,會(huì)給網(wǎng)絡(luò)傳輸帶來(lái)極大的開銷。
  • 序列化的性能太低,對(duì)于高性能的網(wǎng)絡(luò)架構(gòu)是極其不友好的。

主流的編解碼框架

  • Google的Protobuf。
  • Facebok的Thrift。
  • Jboss Marshalling
  • MessagePack

這幾類編解碼框架都有各自的特點(diǎn),有興趣的童鞋可以自己對(duì)其進(jìn)行研究。

我們這里主要對(duì)MessagePack進(jìn)行講解。

MessagePack簡(jiǎn)介

MessagePack是一個(gè)高效的二進(jìn)制序列化框架,它像JSON一樣支持不同的語(yǔ)言間的數(shù)據(jù)交換,并且它的性能更快,序列化之后的碼流也更小。

它的特點(diǎn)如下:

  • 編解碼高效,性能高
  • 序列化之后的碼流小,利于網(wǎng)絡(luò)傳輸或存儲(chǔ)
  • 支持跨語(yǔ)言

MessagePack Java Api的使用

首先導(dǎo)包

<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack -->
<dependency>
  <groupId>org.msgpack</groupId>
  <artifactId>msgpack</artifactId>
  <version>0.6.12</version>
</dependency>

使用API進(jìn)行編碼和解碼

List<String> nameList = new ArrayList<String>();
nameList.add("Tom");
nameList.add("Jack");
MessagePack messagePack = new MessagePack();
//開始序列化
byte[] raw = messagePack.write(nameList);
//使用MessagePack的模版,來(lái)接序列化后的字節(jié)數(shù)組轉(zhuǎn)換為L(zhǎng)ist
List<String> deNameList = messagePack.read(raw,Templates.tList(Templates.TString));
System.out.println(deNameList.get(0));
System.out.println(deNameList.get(1));
System.out.println(deNameList.get(2));

Netty中如何使用MessagePack

編碼器的實(shí)現(xiàn)

public class MsgpackEncoder extends MessageToByteEncoder {

  @Override
  protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
    MessagePack msgpack = new MessagePack();
    //使用MessagePack對(duì)要發(fā)送的數(shù)據(jù)進(jìn)行序列化
    byte[] raw = msgpack.write(msg);
    out.writeBytes(raw);
    
  }

}

解碼器的實(shí)現(xiàn)

public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf> {

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
    //從msg中獲取需要解碼的byte數(shù)組
    final int length = msg.readableBytes();
    byte[] b = new byte[length];
    msg.getBytes(msg.readerIndex(), b,0,length);
    //使用MessagePack的read方法將其反序列化成Object對(duì)象,并加入到解碼列表out中
    MessagePack msgpack = new MessagePack();
    out.add(msgpack.read(b));
  }

}

實(shí)現(xiàn)該編碼器和解碼器的Netty服務(wù)端

public class NettyServer {
  public void bind(int port) throws Exception {
    EventLoopGroup bossGruop = new NioEventLoopGroup();
    EventLoopGroup workGroup = new NioEventLoopGroup();
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGruop, workGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel socketChannel) throws Exception {
            // TODO Auto-generated method stub
            socketChannel.pipeline()
             //添加支持粘包、拆包解碼器,意義:從頭兩個(gè)字節(jié)解析出數(shù)據(jù)的長(zhǎng)度,并且長(zhǎng)度不超過(guò)1024個(gè)字節(jié)
            .addLast("frameDecoder",new LengthFieldBasedFrameDecoder(1024, 0, 2,0,2))
             //反序列化解碼器
            .addLast("msgpack decoder",new MsgpackDecoder())
             //添加支持粘包、拆包編碼器,發(fā)送的每個(gè)數(shù)據(jù)都在頭部增加兩個(gè)字節(jié)表消息長(zhǎng)度
            .addLast("frameEncoder",new LengthFieldPrepender(2))
             //序列化編碼器
            .addLast("msgpack encoder",new MsgpackEncoder()
             //后續(xù)自己的業(yè)務(wù)邏輯
            .addLast(new ServerHandler());
          }
        });
    try {
      ChannelFuture future = bootstrap.bind(port).sync();
      future.channel().closeFuture().sync();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      bossGruop.shutdownGracefully();
      workGroup.shutdownGracefully();
    }
  }
}  

實(shí)現(xiàn)該編碼器和解碼器的Netty客戶端

public class NettyClient {
  private void bind(int port, String host) {
    EventLoopGroup group = new NioEventLoopGroup();
    Bootstrap b = new Bootstrap();
    b.group(group)
        .channel(NioSocketChannel.class)
        .option(ChannelOption.TCP_NODELAY, true)
        .handler(new ChannelInitializer<SocketChannel>(){
          @Override
          protected void initChannel(SocketChannel socketChannel) throws Exception {
            // TODO Auto-generated method stub
            socketChannel.pipeline()
            .addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2))
            .addLast("msgpack decoder", new MsgpackDecoder())
            .addLast("frameEncoder", new LengthFieldPrepender(2))
            .addLast("msgpack encoder", new MsgpackEncoder())
            .addLast(new ClientHandler());
          }
        });
    try {
      ChannelFuture f = b.connect(host, port).sync();
      f.channel().closeFuture().sync();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      group.shutdownGracefully();
    }
  }
}

可以看出客戶端的代碼與服務(wù)端基本相同,所以啊,如果能熟練掌握Netty,今后在自己的項(xiàng)目中運(yùn)用上定制化編解碼的傳輸,將會(huì)是一件十分簡(jiǎn)單的活路。

總結(jié)

無(wú)論是之前解決粘包拆包問(wèn)題,還是這里的使用序列化框架來(lái)進(jìn)行編解碼。我相信讀者學(xué)習(xí)到這里,對(duì)于Netty的使用都有了較為全面的了解。其實(shí)Netty幫我們解決了很多底層棘手問(wèn)題,如客戶端斷連、句柄泄漏和消息丟失等等。所以我們才能十分簡(jiǎn)單開發(fā)出一個(gè)穩(wěn)定的網(wǎng)絡(luò)通訊項(xiàng)目。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法

    Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Java中String的JdbcTemplate連接SQLServer數(shù)據(jù)庫(kù)的方法,在研發(fā)過(guò)程中我們需要與其他系統(tǒng)對(duì)接的場(chǎng)景,連接SQLServer拉取數(shù)據(jù),所以就用jdbc連接數(shù)據(jù)庫(kù)的方式連接外部數(shù)據(jù)源,需要的朋友可以參考下
    2021-10-10
  • springboot整合kaptcha生成驗(yàn)證碼功能

    springboot整合kaptcha生成驗(yàn)證碼功能

    這篇文章主要介紹了springboot整合kaptcha生成驗(yàn)證碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    Java實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • xxl-job定時(shí)任務(wù)配置應(yīng)用及添加到springboot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)API調(diào)用

    xxl-job定時(shí)任務(wù)配置應(yīng)用及添加到springboot項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)API調(diào)用

    XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺(tái),其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡(jiǎn)單、輕量級(jí)、易擴(kuò)展,本篇文章主要是對(duì)xuxueli的xxl-job做一個(gè)簡(jiǎn)單的配置,以及將其添加到自己已有的項(xiàng)目中進(jìn)行api調(diào)用,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑

    java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑

    這篇文章主要介紹了java實(shí)現(xiàn)下載文件到默認(rèn)瀏覽器路徑,具有很好的參考價(jià)值,希望對(duì)的大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 詳解Java如何通過(guò)裝飾器模式擴(kuò)展系統(tǒng)功能

    詳解Java如何通過(guò)裝飾器模式擴(kuò)展系統(tǒng)功能

    這篇文章主要為大家詳細(xì)介紹了Java如何通過(guò)裝飾器模式擴(kuò)展系統(tǒng)功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-04-04
  • Spring?Boot中的過(guò)濾器攔截器監(jiān)聽器使用技巧匯總

    Spring?Boot中的過(guò)濾器攔截器監(jiān)聽器使用技巧匯總

    本文將介紹在Spring?Boot應(yīng)用程序中使用過(guò)濾器、攔截器和監(jiān)聽器的使用技巧,我們將討論它們之間的區(qū)別,以及何時(shí)使用它們,我們還將提供代碼示例,以幫助您在自己的應(yīng)用程序中使用它們
    2023-12-12
  • SpringBoot整合Retry實(shí)現(xiàn)錯(cuò)誤重試過(guò)程逐步介紹

    SpringBoot整合Retry實(shí)現(xiàn)錯(cuò)誤重試過(guò)程逐步介紹

    重試的使用場(chǎng)景比較多,比如調(diào)用遠(yuǎn)程服務(wù)時(shí),由于網(wǎng)絡(luò)或者服務(wù)端響應(yīng)慢導(dǎo)致調(diào)用超時(shí),此時(shí)可以多重試幾次。用定時(shí)任務(wù)也可以實(shí)現(xiàn)重試的效果,但比較麻煩,用Spring Retry的話一個(gè)注解搞定所有,感興趣的可以了解一下
    2023-02-02
  • Spring Boot 集成 Kafka的詳細(xì)步驟

    Spring Boot 集成 Kafka的詳細(xì)步驟

    Spring Boot與Kafka的集成使得消息隊(duì)列的使用變得更加簡(jiǎn)單和高效,可以配置 Kafka、實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者,并利用 Spring Boot 提供的功能處理消息流,以下是 Spring Boot 集成 Kafka 的詳細(xì)步驟,包括配置、生產(chǎn)者和消費(fèi)者的實(shí)現(xiàn)以及一些高級(jí)特性,感興趣的朋友一起看看吧
    2024-07-07
  • Springboot Thymeleaf實(shí)現(xiàn)HTML屬性設(shè)置

    Springboot Thymeleaf實(shí)現(xiàn)HTML屬性設(shè)置

    這篇文章主要介紹了Springboot Thymeleaf實(shí)現(xiàn)HTML屬性設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2007-11-11

最新評(píng)論