一.簡(jiǎn)介
在上一篇博文中筆者已經(jīng)介紹了google的Protocol Buffer的使用,那么本文筆者就開(kāi)始介紹netty對Protocol Buffer的支持。
二.編碼的實(shí)現
2.1 服務(wù)端啟動(dòng)代碼
public class ServerTest { 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 ServerChannelInitilizer()); ChannelFuture channelFuture = serverBootstrap.bind(8989).sync(); channelFuture.channel().closeFuture().sync(); }finally{ bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}
2.2 服務(wù)端管道初始化代碼
public class ServerChannelInitilizer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); /** * 采用Base 128 Varints進(jìn)行編碼,在消息頭上加上32個(gè)整數,來(lái)標注數據的長(cháng)度。 */ pipeline.addLast("protobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder()); pipeline.addLast("protobufDecoder", new ProtobufDecoder(PersonsBook.AddressBook.getDefaultInstance())); /** * 對采用Base 128 Varints進(jìn)行編碼的數據解碼 */ pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("serverHandler", new ServerHandler()); }}
2.3 服務(wù)端Handler處理
public class ServerHandler extends SimpleChannelInboundHandler<AddressBook>{ @Override protected void channelRead0(ChannelHandlerContext ctx, AddressBook msg) throws Exception { List<Person> list = msg.getPersonList(); list.forEach(p -> System.out.println(p.getName() + ";;" + p.getId() + ";;" + p.getEmail())); }}
2.4 客戶(hù)端啟動(dòng)程序
public class ClientTest { 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 ClientChannelInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost", 8989).sync(); channelFuture.channel().closeFuture().sync(); }finally{ eventLoopGroup.shutdownGracefully(); } }}
2.5客戶(hù)端通道初始化
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("protobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder()); pipeline.addLast("protobufDecoder", new ProtobufDecoder(PersonsBook.AddressBook.getDefaultInstance())); pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("clientHandler", new ClientHandler()); }}
2.6 客戶(hù)端Handler處理代碼
public class ClientHandler extends SimpleChannelInboundHandler<AddressBook>{ @Override protected void channelRead0(ChannelHandlerContext ctx, AddressBook msg) throws Exception { } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { AddressBook ab = AddressBook.newBuilder() .addPerson(Person.newBuilder().setEmail("123@qq.com").setId(23).setName("zhangsan")) .addPerson(Person.newBuilder().setEmail("789@163.com").setId(45).setName("lisi")) .build(); ctx.writeAndFlush(ab); }}
三.程序運行
先運行服務(wù)端啟動(dòng)代碼,在運行客戶(hù)端啟動(dòng)代碼。
聯(lián)系客服