Protobuf多协议
2024-08-31 15:01:08
上一篇只有Person的message,如果多了一个message,如Dog,这样就会有问题。
解决方法: 定义多协议
一、定义proto文件
syntax = "proto2"; package com.example.protobuf; option optimize_for = SPEED;
option java_package = "com.example.sixthexample";
option java_outer_classname = "MyDataInfo"; message MyMessage{
enum DataType{
PersonType = 1;
DogType = 2;
CatType = 3;
} required DataType data_type = 1;
oneof dataBody{
Person person = 2;
Dog dog = 3;
Cat cat = 4;
} } message Person{
optional string name = 1;
optional int32 age = 2;
optional string address = 3; } message Dog{
optional string name = 1;
optional int32 age = 2;
} message Cat{
optional string name = 1;
optional string city = 2;
}
然后用命令生成
D:\workspace\study\basic\netty_demo>protoc --java_out=src/main/java src/protobuf/Person2.proto
二、客户端代码
1、TestClient 类,和上一篇一样
public class TestClient { 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 TestClientInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost",8899).sync();
channelFuture.channel().closeFuture().sync(); }finally {
eventLoopGroup.shutdownGracefully();
}
}
}
2、TestClientHandle 类
public class TestClientHandle extends SimpleChannelInboundHandler<MyDataInfo.Person> { // 对于客户端来说,输入来自控制台
@Override
protected void channelRead0(ChannelHandlerContext ctx, MyDataInfo.Person msg) throws Exception { } @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//客户端启动后,将消息发送给服务端
int randomInt = new Random().nextInt(3);
MyDataInfo.MyMessage myMessage = null;
if(0 == randomInt){
MyDataInfo.Person person = MyDataInfo.Person.newBuilder()
.setName("张三").setAge(30).setAddress("上海").build(); myMessage = MyDataInfo.MyMessage.newBuilder()
.setDataType(MyDataInfo.MyMessage.DataType.PersonType)
.setPerson(person).build(); }else if(1 == randomInt){
MyDataInfo.Dog dog = MyDataInfo.Dog.newBuilder()
.setName("一只狗").setAge(10).build(); myMessage = MyDataInfo.MyMessage.newBuilder()
.setDataType(MyDataInfo.MyMessage.DataType.DogType)
.setDog(dog).build();
}else{
MyDataInfo.Cat dog = MyDataInfo.Cat.newBuilder()
.setName("一只猫").setCity("杭州").build(); myMessage = MyDataInfo.MyMessage.newBuilder()
.setDataType(MyDataInfo.MyMessage.DataType.CatType)
.setCat(dog).build();
} ctx.channel().writeAndFlush(myMessage); }
}
3、TestClientInitializer 改变的地方,如下图红色部分
三、服务端
1、TestServer 和上一篇一样
public class TestServer { 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 TestServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
2、TestServerHandle 类
public class TestServerHandle extends SimpleChannelInboundHandler<MyDataInfo.MyMessage> { @Override
protected void channelRead0(ChannelHandlerContext ctx, MyDataInfo.MyMessage msg) throws Exception {
System.out.println("---- 服务端接收到消息 ----");
MyDataInfo.MyMessage.DataType dataType = msg.getDataType();
if(dataType == MyDataInfo.MyMessage.DataType.PersonType){
MyDataInfo.Person person = msg.getPerson();
System.out.println(person.getName());
System.out.println(person.getAge());
System.out.println(person.getAddress());
}else if(dataType == MyDataInfo.MyMessage.DataType.DogType){
MyDataInfo.Dog dog = msg.getDog();
System.out.println(dog.getName());
System.out.println(dog.getAge()); }else {
MyDataInfo.Cat cat = msg.getCat();
System.out.println(cat.getName());
System.out.println(cat.getCity()); } }
}
3、TestServerInitializer 改变的地方,如下图红色部分
四、测试
1、启动服务端
2、启动多个客户端
3、服务端输出
最新文章
- PHP数组的基础知识
- android文件的写入与读取---简单的文本读写context.openFileInput() context.openFileOutput()
- SQL单表查询案例
- Linux(CentOS)中安装MongoDB
- 【wikioi】1029 遍历问题
- python_way ,day22 tonardo
- Apache httpd开启SSL
- random随机函数
- Linux 调度器模拟
- python集合set,frozenset--笔记
- 1.tomcat部署项目的几种方式和weblogic部署方式及一点通讯
- hdu 5650 so easy (异或)
- taobao面试要点
- FACE++学习二、获得face属性
- JVM堆内存设置
- poi java读取excel文件
- 图书馆管理系统(C语言)
- hibrnate缓存
- 使用Eclipse的代码追踪功能
- 【python】numpy中的shape用法
热门文章
- ETC1/DXT1 compressed textures are not supported when publishing to iPhone
- iview blur事件
- day 04 作业 预科
- Linux--基本目录
- Class.getDeclaredFields()和Class.getFields()的区别。 Class.getMethods()和Class.getDeclaredMethods()的区别。
- 关于ssh_config和sshd_config
- CentOS6.5_x64上简单编译配置Heartbeat3.0.4
- PAT甲级1004题解——并查集思想改
- Maven之setting.xml 配置详解
- 小程序之程序构造器App()