Netty中集成Protobuf实现Java对象数据传递
場(chǎng)景
Netty的Socket編程詳解-搭建服務(wù)端與客戶端并進(jìn)行數(shù)據(jù)傳輸:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108615023
ProtoBuf的介紹以及在Java中使用protobuf將對(duì)象進(jìn)行序列化與反序列化:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108667427
在上面兩篇博客基礎(chǔ)上,對(duì)于Socket搭建服務(wù)端和客戶端進(jìn)行通信以及
在Java中Protobuf的使用已經(jīng)有了初步的理解。
那么怎樣使用Netty進(jìn)行服務(wù)端和客戶端的通信時(shí)使用protobuf進(jìn)行數(shù)據(jù)傳遞。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號(hào)
霸道的程序猿
獲取編程相關(guān)電子書(shū)、教程推送與免費(fèi)下載。
實(shí)現(xiàn)
在src下新建protobuf目錄,目錄下新建Person.prpto描述文件
syntax = "proto3";package com.badao.protobuf;option optimize_for =SPEED; option java_package = "com.badao.NettyProtobuf"; option java_outer_classname = "BadaoDataInfo";message Person {string name = 1;int32 age = 2;string address = 3; }具體的講解可以見(jiàn)上面的博客。
然后在src/main/java下新建包c(diǎn)om.badao.NettyProtobuf
打開(kāi)終端Ternimal,使用protoc進(jìn)行編譯代碼
protoc --java_out=src/main/java src/protobuf/Person.proto然后就會(huì)在上面NettyProtobuf包下生成BadaoDataInfo類
上面具體的流程與講解參照上面的博客。
然后新建服務(wù)端類NettyProtobufServer
package com.badao.NettyProtobuf;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler;public class NettyProtobufServer {public static void main(String[] args) throws? Exception{EventLoopGroup bossGroup = new NioEventLoopGroup();EventLoopGroup workerGroup = new NioEventLoopGroup();try{ServerBootstrap serverBootstrap = new ServerBootstrap();serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new NettyProtobufInitializer());//綁定端口ChannelFuture channelFuture = serverBootstrap.bind(70).sync();channelFuture.channel().closeFuture().sync();}finally {//關(guān)閉事件組bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}} }其中用到了自定義的初始化器NettyProtoInitilizer
package com.badao.NettyProtobuf;import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;public class NettyProtobufInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new ProtobufVarint32FrameDecoder());pipeline.addLast(new ProtobufDecoder(BadaoDataInfo.Person.getDefaultInstance()));pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());pipeline.addLast(new ProtobufEncoder());pipeline.addLast(new NettyProtobufHandler());} }注意這里不同的是添加的處理器是Netty自帶的關(guān)于Protobuf的解碼編碼的處理器。
其中Decode處理器的參數(shù)就是上面生成的代碼的默認(rèn)的實(shí)例。
然后最后又添加了自定義的處理器NettyProtobufHandler
package com.badao.NettyProtobuf;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;public class NettyProtobufHandler extends SimpleChannelInboundHandler<BadaoDataInfo.Person> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, BadaoDataInfo.Person msg) throws Exception {System.out.println(msg.getName());System.out.println(msg.getAge());System.out.println(msg.getAddress());} }自定義處理器中在收到發(fā)送的消息時(shí)將消息進(jìn)行輸出,這里這里在繼承SimpleChannelInboundHandler
的泛型就是上面生成的類。
然后新建客戶端類
package com.badao.NettyProtobuf;import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel;public class NettyProtobufClient {public static void main(String[] args) throws? Exception {EventLoopGroup eventLoopGroup = new NioEventLoopGroup();try {Bootstrap bootstrap = new Bootstrap();bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new NettyProtoBufClientInitializer());//綁定端口ChannelFuture channelFuture = bootstrap.connect("localhost", 70);channelFuture.channel().closeFuture().sync();} finally {//關(guān)閉事件組eventLoopGroup.shutdownGracefully();}} }編寫其用到的初始化器
package com.badao.NettyProtobuf;import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.protobuf.ProtobufDecoder; import io.netty.handler.codec.protobuf.ProtobufEncoder; import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;public class NettyProtoBufClientInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new ProtobufVarint32FrameDecoder());pipeline.addLast(new ProtobufDecoder(BadaoDataInfo.Person.getDefaultInstance()));pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());pipeline.addLast(new ProtobufEncoder());pipeline.addLast(new NettyProtobufClientHandler());} }和服務(wù)端的初始化器用到的處理器一致,最后也要有自定義的處理器
package com.badao.NettyProtobuf;import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler;public class NettyProtobufClientHandler extends SimpleChannelInboundHandler<BadaoDataInfo.Person> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, BadaoDataInfo.Person msg) throws Exception {}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {BadaoDataInfo.Person person = BadaoDataInfo.Person.newBuilder().setName("公眾號(hào):霸道的程序猿").setAge(100).setAddress("中國(guó)").build();ctx.channel().writeAndFlush(person);} }在與服務(wù)端建立連接即通道激活的回調(diào)方法中向服務(wù)端發(fā)送數(shù)據(jù)。
然后運(yùn)行服務(wù)端的main方法再運(yùn)行客戶端的main方法。
?
示例代碼下載
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12863005
與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Netty中集成Protobuf实现Java对象数据传递的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ProtoBuf的介绍以及在Java中使
- 下一篇: Thrift介绍以及Java中使用Thr