Protobuf多协议
上一篇只有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多协议的更多相关文章
- netty中使用protobuf实现多协议的消息
		在我们使用 netty 的过程中,有时候为了高效的传输数据,经常使用 protobuf 进行数据的传输,netty默认情况下为我们实现的 protobuf 的编解码,但是默认的只能实现单个对象的编解码 ... 
- Netty对Protocol Buffer多协议的支持(八)
		Netty对Protocol Buffer多协议的支持(八) 一.背景 在上篇博文中笔者已经用代码演示了如何在netty中使用Protocol Buffer,然而细心的用户可能会发现一个明显的不足之处 ... 
- python通过protobuf实现rpc
		由于项目组现在用的rpc是基于google protobuf rpc协议实现的,所以花了点时间了解下protobuf rpc.rpc对于做分布式系统的人来说肯定不陌生,对于rpc不了解的童鞋可以自行g ... 
- Protobuf使用规范分享
		一.Protobuf 的优点 Protobuf 有如 XML,不过它更小.更快.也更简单.它以高效的二进制方式存储,比 XML 小 3 到 10 倍,快 20 到 100 倍.你可以定义自己的数据结构 ... 
- java netty socket库和自定义C#socket库利用protobuf进行通信完整实例
		之前的文章讲述了socket通信的一些基本知识,已经本人自定义的C#版本的socket.和java netty 库的二次封装,但是没有真正的发表测试用例. 本文只是为了讲解利用protobuf 进行C ... 
- 在Wcf中应用ProtoBuf替代默认的序列化器
		Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ... 
- protobuf的编译安装
		github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在centos7下编译源码进行安装. github上有详细的安装说明: ... 
- 编译protobuf的jar文件
		1.准备工作 需要到github上下载相应的文件,地址https://github.com/google/protobuf/releases protobuf有很多不同语言的版本,因为我们需要的是ja ... 
- protobuf学习(2)-相关学习资料
		protobuf官方git地址 protobuf官方英文文档 (你懂的需要FQ) protobuf中文翻译文档 protobuf概述 (官方翻译 推荐阅读) protobuf入门 ... 
随机推荐
- Windows上安装ElasticSearch7
			安装JDK1.8(包括)以上版本 安装ElasticSearch ElasticSearch下载地址: https://www.elastic.co/downloads/elasticsearch 双 ... 
- github hooks 配置教程 钩子搭建(实测通过,手把手教程)
			tips:如果本文对你有用,请爱心点个赞,提高排名,让这篇文章帮助更多的人.谢谢大家!❤ 本人hooks搭建成功,全程参考JellyBool老师的视频教程,有不懂的可以先去看下这个视频,跟着操作.本文 ... 
- LFS7.10——构建LFS系统
			参考:LFS7.10——准备Host系统 LFS7.10——构造临时Linux系统 本文正式开始构建LFS系统,后面所有命令的执行都是在root用户下完成的. 这时开始构建LFS前准备工作 更改$LF ... 
- 如何在Jenkins中使用日期参数(变量)
			一.首先需要安装插件:Date Parameter Plugin 二.安装完成后,在项目中添加参数,我这里只有日期,时间的话没试过,应该也可以把 三.用${date}调用参数即可 最后邮件的附件正常~ 
- 【转】GnuPG使用介绍
			一.什么是 GPG 要了解什么是 GPG,就要先了解 PGP. 1991 年,程序员 Phil Zimmermann 为了避开政府监视,开发了加密软件 PGP.这个软件非常好用,迅速流传开来,成了许多 ... 
- django考点答案
			1 列举Http请求中常见的请求方式 2 谈谈你对HTTP协议的认识.1.1 长连接3 简述MVC模式和MVT模式4 简述Django请求生命周期5 简述什么是FBV和CBV6 谈一谈你对ORM的理解 ... 
- uiautomator2+python自动化测试2-查看app页面元素利器weditor
			前言 android sdk里面自带的uiautomatorviewer.bat可以查看手机app上的元素,但是不太好用,网上找了个大牛写的weditor,试用了下还是蛮不错的 python环境:3. ... 
- 安卓Termux安装ssh及jupyter编程
			软件名称:Termux ssh安装 安装openssh apt update apt install openssh 启动ssh服务 sshd 配置公钥私钥 将电脑的公钥(id_rsa.pub)放入/ ... 
- test20190901 NOI2019 模拟赛
			0+0+0=0.还是太菜,看不出题型. Masodik 你要从 (0,0) 点走到 (n,m),每次只能往 x 轴或者 y 轴正方向移动一个单位距离.从 (i,j) 移动到 (i,j+1) 的代价为 ... 
- Idea中,项目文件右键菜单没有svn选项处理办法
			问题描述 IntelliJ IDEA打开带SVN信息的项目,在项目文件上点击右键,菜单中没有Subversion的功能项,如下图: 解决办法 点击菜单:VCS -> Enabled Versio ... 
