Netty对Protocol Buffer多协议的支持(八)

Netty对Protocol Buffer多协议的支持(八)

一.背景

  在上篇博文中笔者已经用代码演示了如何在netty中使用Protocol Buffer,然而细心的用户可能会发现一个明显的不足之处就是,我们的Handler只能处理一种特定的类型,而我们的项目中又不可能只有一种类型,那么这个问题该怎么解决了?多的不说,笔者直接上代码。

二.代码实现

2.1 message的编写

syntax = "proto2";
package com.rsy.netty.protobuf;
option java_package = "com.rsy.netty.protobuf";
option java_outer_classname = "DataInfo"; message Datas{
enum DataType {
personType = ;
dogType = ;
} required DataType data_type = ; oneof type_data{
Person person = ;
Dog dog = ;
}
} message Person{
required int32 id = ;
optional string name = ; enum Gender {
male = ;
female = ;
} optional Gender gender = ;
} message Dog {
required float height = ;
optional string color = ;
optional int64 age = ;
}

2.2 生成Java代码,在此不再赘述。

2.3 服务端启动代码

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.4 服务端通道初始化代码

public class ServerChannelInitilizer 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(DataInfo.Datas.getDefaultInstance())); pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("serverHandler", new ServerHandler());
}
}

2.5 服务端Handler代码

public class ServerHandler extends SimpleChannelInboundHandler<DataInfo.Datas>{

    @Override
protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Datas msg) throws Exception {
/**
* 因为最先写过来的是Person
*/
DataInfo.Person p = msg.getPerson(); System.out.println(msg.getDataType().toString());
System.out.println(p.getId());
System.out.println(p.getGender().toString());
System.out.println(p.getName()); DataInfo.Datas data = DataInfo.Datas.newBuilder()
.setDataType(DataType.dogType)
.setDog(
DataInfo.Dog.newBuilder()
.setAge(23)
.setColor("红色")
.setHeight(3.5f)
).build();
ctx.writeAndFlush(data);
}
}

2.6 客户端启动代码

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.7 客户端通道初始化代码

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(DataInfo.Datas.getDefaultInstance()));
pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("clientHandler", new ClientHandler());
}
}

2.8 客户端Handler处理代码

public class ClientHandler extends SimpleChannelInboundHandler<DataInfo.Datas>{

    @Override
protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Datas msg) throws Exception {
/**
* 服务端写回来的是dog
*/
DataInfo.Dog dog = msg.getDog(); System.out.println(msg.getDataType().toString());
System.out.println(dog.getAge());
System.out.println(dog.getColor());
System.out.println(dog.getHeight());
} @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { DataInfo.Datas data = DataInfo.Datas.newBuilder()
.setDataType(DataType.personType)
.setPerson(
DataInfo.Person.newBuilder()
.setId(23)
.setGender(Gender.female)
.setName("zhangsan")
)
.build(); ctx.writeAndFlush(data);
}
}

三.运行

  运行服务端启动代码,再运行客户端启动代码。

上一篇:Asp.net 菜单控件


下一篇:PTA8