上一篇只有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、服务端输出

Protobuf多协议的更多相关文章

  1. netty中使用protobuf实现多协议的消息

    在我们使用 netty 的过程中,有时候为了高效的传输数据,经常使用 protobuf 进行数据的传输,netty默认情况下为我们实现的 protobuf 的编解码,但是默认的只能实现单个对象的编解码 ...

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

    Netty对Protocol Buffer多协议的支持(八) 一.背景 在上篇博文中笔者已经用代码演示了如何在netty中使用Protocol Buffer,然而细心的用户可能会发现一个明显的不足之处 ...

  3. python通过protobuf实现rpc

    由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ...

  4. Protobuf使用规范分享

    一.Protobuf 的优点 Protobuf 有如 XML,不过它更小.更快.也更简单.它以高效的二进制方式存储,比 XML 小 3 到 10 倍,快 20 到 100 倍.你可以定义自己的数据结构 ...

  5. java netty socket库和自定义C#socket库利用protobuf进行通信完整实例

    之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ...

  6. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  7. protobuf的编译安装

    github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在centos7下编译源码进行安装. github上有详细的安装说明: ...

  8. 编译protobuf的jar文件

    1.准备工作 需要到github上下载相应的文件,地址https://github.com/google/protobuf/releases protobuf有很多不同语言的版本,因为我们需要的是ja ...

  9. protobuf学习(2)-相关学习资料

    protobuf官方git地址 protobuf官方英文文档   (你懂的需要FQ) protobuf中文翻译文档 protobuf概述          (官方翻译 推荐阅读) protobuf入门 ...

随机推荐

  1. Hybris服务器启动日志分析

    build文件检测,使用b2c_acc recipit启动服务器:/home/jerrywang/Hybris/installer/recipes/b2c_acc/build.gradle The T ...

  2. idea2018.3导入grails项目,无法正常使用问题解决

    注:作者的grails版本为2.0.4,grails3版本以上的导入方式为gradle方式 一.导入grails项目 1.启动新项目向导.如果IntelliJ IDEA目前没有打开任何项目,请在欢迎屏 ...

  3. AIX安装单实例11gR2 GRID+DB

    AIX安装单实例11gR2 GRID+DB   一.1  BLOG文档结构图       一.2  前言部分   一.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以 ...

  4. 11g包dbms_parallel_execute在海量数据处理过程中的应用

    11g包dbms_parallel_execute在海量数据处理过程中的应用 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也 ...

  5. 系统调用之fork()用法及陷阱

    Fork System Call The fork system call is used to create a new processes. The newly created process i ...

  6. linux查看redis安装目录

    1.在redis下查看安装目录 如果命令 which 和whereis 都找不到安装目录,可使用以下办法 ps -ef|grep redis 得到了进程号 xxxx 然后 ls -l /proc/xx ...

  7. maven打包成可运行的jar

    在pom.xml添加 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</ ...

  8. unicode转换为中文

    unicode转换为中文 \u5f53\u5730\u65f6\u95f42019\u5e747\u670813\u65e5\uff0c\u82f1\u56fd\u8d1d\u5fb7\u798f\u ...

  9. Alpha冲刺(10/10)——2019.5.3

    所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(10/10)--2019.5.3 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...

  10. PHP——仿造微信OpenId

    前言 这就是拿来玩的,其次假的就是假的,成不了真的! 代码 首先我观察了两个公众号关注后的生成openid的规则,发现了以下规则 1. OpenID都是28位 2. 前六位是有规律的 然后接下来就按着 ...