netty粘包(十)ProtobufDecoder & ProtobufEncoder

syntax = "proto2";
package myproto;

option java_package = "com.jds.test.proto";
option java_outer_classname = "MyBaseProto";

enum Type {
	ONE = 1;
	TWO = 2;
	THREE = 3;
}

message Body {
	repeated string l = 1; // repeated 列表
	map<string, string> m = 2; //
	optional Type type = 3;
} 

message BaseProto {
	required int32 code = 1;//   默认值,表示成员只有0个或者1个
	required string msg = 2;// 
	optional Body result = 3;
}

  

msg.proto

protoc-3.6.1-osx-x86_64/bin/protoc --proto_path ./ --java_out ./ msg.proto

 

class ClientHandler4 extends SimpleChannelInboundHandler<MyBaseProto.BaseProto> {

    //接受服务端发来的消息
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MyBaseProto.BaseProto msg) throws Exception {
        System.out.println("server response : "+msg.toString());
    }

    //与服务器建立连接
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //给服务器发消息

        //发送5次消息
        for (int i = 0; i < 5; i++) {
            MyBaseProto.BaseProto.Builder builder = MyBaseProto.BaseProto.newBuilder();
            builder.setCode(i);
            builder.setMsg("msg" + i);
            MyBaseProto.Body.Builder body = MyBaseProto.Body.newBuilder();
            body.addL(String.valueOf(i * 10));
            body.addL(String.valueOf(i * i));
            MyBaseProto.Type type = MyBaseProto.Type.ONE;
            body.setType(type);
            builder.setResult(body);

            ctx.channel().writeAndFlush(builder.build());
        }
    }

 

class ServerHandler4 extends SimpleChannelInboundHandler<MyBaseProto.BaseProto> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MyBaseProto.BaseProto msg) throws Exception {
        System.out.println("RESPONSE--------"+msg.toString());

        MyBaseProto.BaseProto.Builder builder = MyBaseProto.BaseProto.newBuilder(msg);
        builder.setCode(msg.getCode() + 100);
        ctx.writeAndFlush(builder.build()).

  

 

                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    //获取管道
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new LengthFieldBasedFrameDecoder(10000, 0, 4, 0, 4));
                    pipeline.addLast(new ProtobufDecoder(MyBaseProto.BaseProto.getDefaultInstance()));
                    pipeline.addLast(new LengthFieldPrepender(4));
                    pipeline.addLast(new ProtobufEncoder());
                    //处理类
                    pipeline.addLast(new ClientHandler4());
                }
            });

  

            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    //获取管道
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    pipeline.addLast(new LengthFieldBasedFrameDecoder(10000, 0, 4, 0, 4));
                    pipeline.addLast(new ProtobufDecoder(MyBaseProto.BaseProto.getDefaultInstance()));
                    pipeline.addLast(new LengthFieldPrepender(4));
                    pipeline.addLast(new ProtobufEncoder());
                    //处理类
                    pipeline.addLast(new ServerHandler4());
                }
            });

  

+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.6.1</version>
+        </dependency>

  

 服务端输出:

fanxindeMacBook-Air:action sunyuming$ java -jar target/netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 
server start ...... 
channelActive
RESPONSE--------code: 0
msg: "msg0"
result {
  l: "0"
  l: "0"
  type: ONE
}

RESPONSE--------code: 1
msg: "msg1"
result {
  l: "10"
  l: "1"
  type: ONE
}

RESPONSE--------code: 2
msg: "msg2"
result {
  l: "20"
  l: "4"
  type: ONE
}

RESPONSE--------code: 3
msg: "msg3"
result {
  l: "30"
  l: "9"
  type: ONE
}

RESPONSE--------code: 4
msg: "msg4"
result {
  l: "40"
  l: "16"
  type: ONE
}

  

客户端输出:

server response : code: 100
msg: "msg0"
result {
  l: "0"
  l: "0"
  type: ONE
}

server response : code: 101
msg: "msg1"
result {
  l: "10"
  l: "1"
  type: ONE
}

server response : code: 102
msg: "msg2"
result {
  l: "20"
  l: "4"
  type: ONE
}

server response : code: 103
msg: "msg3"
result {
  l: "30"
  l: "9"
  type: ONE
}

server response : code: 104
msg: "msg4"
result {
  l: "40"
  l: "16"
  type: ONE
}

  

笔记:

1 protobuf编译器与maven应一致,本例为3.6.1

2 proto2不支持map,但可以运行;proto3不需要optional和required,否则会报错 ;本例为proto2

3 一如既往,netty 4.0.17.Final

posted on 2018-09-20 17:14  silyvin  阅读(423)  评论(0)    收藏  举报