Protobuf集成Netty并且多协议消息传递

1 篇文章 0 订阅
1 篇文章 0 订阅

Protobuf集成Netty并且多协议消息传递

Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing

最近在学习google的protoBuf,大概的瞅了瞅[官网地址](https://developers.google.cn/protocol-buffers)写了一个入门的小程序。
  1. 首先去github上下载protobuf的Compiler ,下载地址
  2. 下载完成之后解压,然后配置环境变量,输入proto --version ,看到版本信息就代表安装成功
    在这里插入图片描述
  3. 接着在idea中编写.proto文件

`

		syntax = "proto2";
		
		package tutorial;
		
		option java_package = "com.example.msg";
		option java_outer_classname = "Message";
		message Notice {
		    enum Type {
		        HomeMsg = 1;
		        WorkMsg = 2;
		    }
		    required Type dataType = 3;
		
		    oneof body {
		        HomeMessage homeMsg = 4;
		        WorkMessage workMsg = 5;
		    }
		}
		
		message HomeMessage {
		    optional int32 id = 1;
		    optional string body = 2;
		    optional string home = 3;
		}
		
		message WorkMessage {
		    optional int32 id = 1;
		    optional string body = 2;
		    optional string work = 3;
		} 						

`

  1. 导入相关的依赖,注意:protobuf的版本和安装的Compiler 版本保持一致,否则生成的java文件会报错

    在这里插入图片描述

  2. 使用protoc --java_out=src/main/java src/proto/message.proto向指定的路径生成java文件

  3. 编写netty服务端程序

6.1服务端启动类
 public class App {
    public static void main(String[] args) throws Exception {
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        try {
            serverBootstrap.group(boss,work).channel(NioServerSocketChannel.class).childHandler(new ServerInitainazer());
            ChannelFuture future = serverBootstrap.bind(8899).sync();
            ChannelFuture sync = future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
}

6.2服务端ServerInitializer


public class ServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(new ProtobufVarint32FrameDecoder());
        pipeline.addLast(new ProtobufDecoder(Message.Notice.getDefaultInstance()));
        pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
        pipeline.addLast(new ProtobufEncoder());
        pipeline.addLast(new ServerHandler());
    }
}

6.3服务端handler

public class ServerHandler extends SimpleChannelInboundHandler<Message.Notice> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Message.Notice notice) throws Exception {
        Message.Notice.Type dataType = notice.getDataType();
        if(dataType == Message.Notice.Type.HomeMsg){
            System.out.println("----------homeMsg------------");
            System.out.println(notice.getHomeMsg().getId());
            System.out.println(notice.getHomeMsg().getBody());
            System.out.println(notice.getHomeMsg().getHome());
        }else if(dataType == Message.Notice.Type.WorkMsg){
            System.out.println("----------workMsg------------");
            System.out.println(notice.getWorkMsg().getId());
            System.out.println(notice.getWorkMsg().getBody());
            System.out.println(notice.getWorkMsg().getWork());
        }
    }
}
  1. 编写netty客户端

    7.1客户端启动类

public class ClientApp {
    public static void main(String[] args) throws Exception {
        EventLoopGroup eventExecutors = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(eventExecutors).channel(NioSocketChannel.class).handler(new ClientInitializer());
        ChannelFuture future = bootstrap.connect("127.0.0.1", 8899).sync();
        future.channel().closeFuture().sync();
    }
}

7.2客户端ClientInitializer

public class ClientInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();
        pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
        pipeline.addLast(new ProtobufDecoder(Message.Notice.getDefaultInstance()));
        pipeline.addLast(new ProtobufVarint32FrameDecoder());
        pipeline.addLast(new ProtobufEncoder());
        pipeline.addLast(new ClientHandler());

    }
}

7.3 客户端handler

public class ClientHandler extends SimpleChannelInboundHandler<Message.Notice> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Message.Notice notice) throws Exception {

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        for(int i = 0; i < 100; i++){
            Message.Notice notice = null;
            if(i%2==0){
                Message.HomeMessage build = Message.HomeMessage.newBuilder().setBody("家庭消息主题").setHome("home").setId(i).build();
                notice = Message.Notice.newBuilder().setDataType(Message.Notice.Type.HomeMsg).setHomeMsg(build).build();
            }else if(i%2==1){
                Message.WorkMessage build = Message.WorkMessage.newBuilder().setBody("工作消息主题").setWork("work").setId(i).build();
                notice = Message.Notice.newBuilder().setDataType(Message.Notice.Type.WorkMsg).setWorkMsg(build).build();
            }
            ctx.channel().writeAndFlush(notice);
        }
    }
}

  1. 整体项目结构

在这里插入图片描述

  1. 运行结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值