netty------編解碼技術(shù)

編解碼技術(shù)說白了就是java序列化技術(shù)淀歇,序列化的目的就兩個易核,一個是進行網(wǎng)絡(luò)傳輸,一個是對象持久化浪默。

我們可以說使用java序列化牡直,用netty進行傳輸,但是java序列化缺點太多纳决。例如:java序列化沒法跨語言碰逸、序列化后碼流太大、序列化性能太低等等阔加。

幾個主流的編解碼框架:
1.google的Protobuf
Protobuf是google開源的項目饵史,全稱 Google Protocol Buffers.特點:

1.結(jié)構(gòu)化數(shù)據(jù)存儲格式(xml,json等)
2.高性能編解碼技術(shù)
3.語言和平臺無關(guān),擴展性好
4.支持java,C++,Python三種語言掸哑。

2.faceBook的Thrift
Thrift源于faceBook约急,2007年facebook將Thrift做為一個開源項目交給了apache基金會零远。特點:

1.Thrift支持多種語言(C++,C#,Cocoa,Erlag,Haskell,java,Ocami,Perl,PHP,Python,Ruby,和SmallTalk)
2.Thrift適用了組建大型數(shù)據(jù)交換及存儲工具苗分,對于大型系統(tǒng)中的內(nèi)部數(shù)據(jù)傳輸,相對于Json和xml在性能上和傳輸大小上都有明顯的優(yōu)勢牵辣。
3.Thrift支持三種比較典型的編碼方式摔癣。(通用二進制編碼,壓縮二進制編碼纬向,優(yōu)化的可選字段壓縮編解碼)

3.JBoss Marshlling介紹
JBoss Marshalling是一個java對象的序列化API包择浊,修正了java自帶的序列化包的很多問題,但又保持跟java.io.Serializable接口的兼容逾条,同時又增加了一些可調(diào)的參數(shù)和附加特性琢岩,并且這些參數(shù)和特性可通過工廠類的配置,师脂,很強大啊有木有担孔。特點:

1.可拔插的類解析器,提供更加便捷的類加載定制策略吃警,通過一個接口即可實現(xiàn)定制糕篇。
2.可拔插的對象替換技術(shù),不需要通過繼承的方式酌心。
3.可拔插的預(yù)定義類緩存表拌消,可以減少序列化的字節(jié)數(shù)組長度,提升常用類型的對象序列化性能安券。
4.無須實現(xiàn)java.io.Serializable接口
5.通過緩存技術(shù)提升對象的序列化性能墩崩。
6.使用非常簡單

接下來就是netty和marshalling代碼 實現(xiàn)序列化了
server端

package com.netty.serialize;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class Server {

    public static void main(String[] args) throws Exception{
        
        EventLoopGroup pGroup = new NioEventLoopGroup();
        EventLoopGroup cGroup = new NioEventLoopGroup();
        
        ServerBootstrap b = new ServerBootstrap();
        b.group(pGroup, cGroup)
         .channel(NioServerSocketChannel.class)
         .option(ChannelOption.SO_BACKLOG, 1024)
         .childHandler(new ChannelInitializer<SocketChannel>() {
            protected void initChannel(SocketChannel sc) throws Exception {
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
                sc.pipeline().addLast(new ServerHandler());
            }
        });
        
        ChannelFuture cf = b.bind(8888).sync();
        
        cf.channel().closeFuture().sync();
        pGroup.shutdownGracefully();
        cGroup.shutdownGracefully();
        
    }
}

servlerHandler

package com.netty.serialize;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends ChannelInboundHandlerAdapter{
    
    /**
     * 通道激活
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("數(shù)據(jù)激活");
    }
    
    /**
     * 通道數(shù)據(jù)讀取
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Req req = (Req) msg;
        System.out.println("服務(wù)器收到數(shù)據(jù):"+ req.getId() + ", " + req.getName() + ", " + req.getRequestMessage());
        
        Resp resp = new Resp();
        resp.setId(req.getId());
        resp.setName("resp" + req.getId());
        resp.setResponseMessage("響應(yīng)內(nèi)容" + req.getId());
        ctx.writeAndFlush(resp);
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("數(shù)據(jù)讀取完畢");
    }
}

client端

package com.netty.serialize;


import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.io.File;
import java.io.FileInputStream;


public class Client {

    
    public static void main(String[] args) throws Exception{
        
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(group)
         .channel(NioSocketChannel.class)
         .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel sc) throws Exception {
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingDecoder());
                sc.pipeline().addLast(MarshallingCodeCFactory.buildMarshallingEncoder());
                sc.pipeline().addLast(new ClientHandler());
            }
        });
        
        ChannelFuture cf = b.connect("127.0.0.1", 8888).sync();
        
        for(int i = 0; i < 5; i++ ){
            Req req = new Req();
            req.setId("" + i);
            req.setName("pro" + i);
            req.setRequestMessage("數(shù)據(jù)信息" + i);  
            cf.channel().writeAndFlush(req);
        }

        cf.channel().closeFuture().sync();
        group.shutdownGracefully();
    }
}

clientHandler

package com.netty.serialize;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

public class ClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("通道激活");
    }
    
    /**
     * 通道數(shù)據(jù)讀取
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            Resp resp = (Resp)msg;
            System.out.println("Client : " + resp.getId() + ", " + resp.getName() + ", " + resp.getResponseMessage());          
        } finally {
            ReferenceCountUtil.release(msg);
        }
        
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("接收返回信息完成");
    }
}

MarshallingCodeCFactory

package com.netty.serialize;

import io.netty.handler.codec.marshalling.DefaultMarshallerProvider;
import io.netty.handler.codec.marshalling.DefaultUnmarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallerProvider;
import io.netty.handler.codec.marshalling.MarshallingDecoder;
import io.netty.handler.codec.marshalling.MarshallingEncoder;
import io.netty.handler.codec.marshalling.UnmarshallerProvider;

import org.jboss.marshalling.MarshallerFactory;
import org.jboss.marshalling.Marshalling;
import org.jboss.marshalling.MarshallingConfiguration;

/**
 * Marshalling工廠
 * @author(alienware)
 */
public final class MarshallingCodeCFactory {

    /**
     * 創(chuàng)建Jboss Marshalling解碼器MarshallingDecoder
     * @return MarshallingDecoder
     */
    public static MarshallingDecoder buildMarshallingDecoder() {
        //首先通過Marshalling工具類的精通方法獲取Marshalling實例對象 參數(shù)serial標識創(chuàng)建的是java序列化工廠對象氓英。
        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
        //創(chuàng)建了MarshallingConfiguration對象,配置了版本號為5 
        final MarshallingConfiguration configuration = new MarshallingConfiguration();
        configuration.setVersion(5);
        //根據(jù)marshallerFactory和configuration創(chuàng)建provider
        UnmarshallerProvider provider = new DefaultUnmarshallerProvider(marshallerFactory, configuration);
        //構(gòu)建Netty的MarshallingDecoder對象泰鸡,倆個參數(shù)分別為provider和單個消息序列化后的最大長度
        MarshallingDecoder decoder = new MarshallingDecoder(provider, 1024 * 1024 * 1);
        return decoder;
    }

    /**
     * 創(chuàng)建Jboss Marshalling編碼器MarshallingEncoder
     * @return MarshallingEncoder
     */
    public static MarshallingEncoder buildMarshallingEncoder() {
        final MarshallerFactory marshallerFactory = Marshalling.getProvidedMarshallerFactory("serial");
        final MarshallingConfiguration configuration = new MarshallingConfiguration();
        configuration.setVersion(5);
        MarshallerProvider provider = new DefaultMarshallerProvider(marshallerFactory, configuration);
        //構(gòu)建Netty的MarshallingEncoder對象债蓝,MarshallingEncoder用于實現(xiàn)序列化接口的POJO對象序列化為二進制數(shù)組
        MarshallingEncoder encoder = new MarshallingEncoder(provider);
        return encoder;
    }
}

請求對象

package com.netty.serialize;

import java.io.Serializable;

public class Req implements Serializable{

    private static final long  SerialVersionUID = 1L;
    
    private String id ;
    private String name ;
    private String requestMessage ;
    private byte[] attachment;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getRequestMessage() {
        return requestMessage;
    }
    public void setRequestMessage(String requestMessage) {
        this.requestMessage = requestMessage;
    }
    public byte[] getAttachment() {
        return attachment;
    }
    public void setAttachment(byte[] attachment) {
        this.attachment = attachment;
    }
    
    


}

返回對象

package com.netty.serialize;

import java.io.Serializable;

public class Resp implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
    private String id;
    private String name;
    private String responseMessage;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getResponseMessage() {
        return responseMessage;
    }
    public void setResponseMessage(String responseMessage) {
        this.responseMessage = responseMessage;
    }
    

}

測試結(jié)果 server端

數(shù)據(jù)激活
服務(wù)器收到數(shù)據(jù):0, pro0, 數(shù)據(jù)信息0
服務(wù)器收到數(shù)據(jù):1, pro1, 數(shù)據(jù)信息1
服務(wù)器收到數(shù)據(jù):2, pro2, 數(shù)據(jù)信息2
服務(wù)器收到數(shù)據(jù):3, pro3, 數(shù)據(jù)信息3
服務(wù)器收到數(shù)據(jù):4, pro4, 數(shù)據(jù)信息4
數(shù)據(jù)讀取完畢

測試結(jié)果 client端

通道激活
Client : 0, resp0, 響應(yīng)內(nèi)容0
接收返回信息完成
Client : 1, resp1, 響應(yīng)內(nèi)容1
Client : 2, resp2, 響應(yīng)內(nèi)容2
Client : 3, resp3, 響應(yīng)內(nèi)容3
Client : 4, resp4, 響應(yīng)內(nèi)容4
接收返回信息完成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盛龄,隨后出現(xiàn)的幾起案子饰迹,更是在濱河造成了極大的恐慌,老刑警劉巖余舶,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啊鸭,死亡現(xiàn)場離奇詭異,居然都是意外死亡匿值,警方通過查閱死者的電腦和手機赠制,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挟憔,“玉大人钟些,你說我怎么就攤上這事“硖罚” “怎么了政恍?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長达传。 經(jīng)常有香客問我篙耗,道長,這世上最難降的妖魔是什么宪赶? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任宗弯,我火速辦了婚禮,結(jié)果婚禮上搂妻,老公的妹妹穿的比我還像新娘蒙保。我一直安慰自己,他們只是感情好欲主,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布邓厕。 她就那樣靜靜地躺著,像睡著了一般岛蚤。 火紅的嫁衣襯著肌膚如雪邑狸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天涤妒,我揣著相機與錄音单雾,去河邊找鬼。 笑死,一個胖子當著我的面吹牛硅堆,可吹牛的內(nèi)容都是我干的屿储。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼渐逃,長吁一口氣:“原來是場噩夢啊……” “哼够掠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茄菊,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤疯潭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后面殖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竖哩,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年脊僚,在試婚紗的時候發(fā)現(xiàn)自己被綠了相叁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡辽幌,死狀恐怖增淹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乌企,我是刑警寧澤虑润,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站逛犹,受9級特大地震影響端辱,放射性物質(zhì)發(fā)生泄漏梁剔。R本人自食惡果不足惜虽画,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荣病。 院中可真熱鬧码撰,春花似錦、人聲如沸个盆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颊亮。三九已至柴梆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間终惑,已是汗流浹背绍在。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人偿渡。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓臼寄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親溜宽。 傳聞我的和親對象是個殘疾皇子吉拳,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 說白了就是java序列化技術(shù)留攒,一是為了網(wǎng)絡(luò)傳輸,二是為了對象持久化嫉嘀,雖然我們可以用java對對象進行序列化稼跳,用ne...
    MicoCube閱讀 277評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)吃沪,斷路器汤善,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 1、Netty基礎(chǔ)入門 Netty是由JBOSS提供的一個java開源框架票彪。Netty提供異步的红淡、事件驅(qū)動的網(wǎng)絡(luò)應(yīng)...
    我是嘻哈大哥閱讀 4,690評論 0 31
  • 社會應(yīng)該給兩種人更多機會,就是青年和窮人降铸!青年應(yīng)該在有思想在旱、有抱負、有精力的時候推掸,獲得施展的平臺桶蝎。窮則思變!變則通...
    再湊熱鬧閱讀 134評論 2 2
  • 誰把篩抖了一抖雨滴紛紛掉落誰把黑袍揚起陰沉冷住了我 車輪卷起片片白花泡沫裹住藍色的腳烏云向遠方低吟翻滾這酸水你也快...
    秋水河閱讀 278評論 0 0