syntax = "proto3";//声明使用proto3的语法 option optimize_for=SPEED;//加快解析 option java_package = "com.zeng.nio.netty.protoBuf2";//指定包名 option java_outer_classname = "DataInfo";//指定生成java类名 message Model{ //申明一个枚举类型 enum ModelType{ StudentType =0; WorkerType=1; } //申明一个属性 ModelType dataType=1; //Student和Worker属性一次只能传输一个 oneof dataBody{ Student student=2; Worker worker=3; } } //申明一个类 message Student { //申明int类型的属性名及次序 int32 id = 1; string name = 2; string email = 3; } message Worker { int32 id = 1; string name = 2; int32 age = 3; }
- 编译命令:protoc --java_out=. proto/DataInfo.proto
- 把 DataInfo.java放到项目中
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
public class Client {
public static void main(String[] args) {
EventLoopGroup group=new NioEventLoopGroup();
try {
Bootstrap bootstrap=new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//1 编码器 解码器
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new ProtobufDecoder(DataInfo.Model.getDefaultInstance()));
//2 自定义处理器:通道连接成功后发送pojo对象消息
pipeline.addLast(new SimpleChannelInboundHandler(){
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//3.1 给服务器端发送student类型的信息
DataInfo.Model msg = DataInfo.Model.newBuilder()
.setDataType(DataInfo.Model.ModelType.StudentType)
.setStudent(
DataInfo.Student.newBuilder()
.setId(0)
.setName("student")
.setEmail("[email protected]")
.build())
.build();
ctx.writeAndFlush(msg);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Model msg) throws Exception {
//3.2 从服务器端收取信息
DataInfo.Model.ModelType dataType = msg.getDataType();
switch (dataType){
case StudentType:
DataInfo.Student student = msg.getStudent();
System.out.println("id:"+student.getId()+" name:"+student.getName()+" email:"+student.getEmail());
break;
case WorkerType:
DataInfo.Worker worker = msg.getWorker();
System.out.println("id:"+worker.getId()+" name:"+worker.getName()+" age:"+worker.getAge());
}
}
});
}
});
ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9999).sync();
channelFuture.addListener(future -> {
if (future.isSuccess())
System.out.println("ok");
else
System.out.println("no");
});
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
public class Server {
public static void main(String[] args){
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//1 编码器 解码器
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new ProtobufDecoder(DataInfo.Model.getDefaultInstance()));
//2 自定义处理器:通道连接成功后接收pojo对象
pipeline.addLast(new SimpleChannelInboundHandler(){
@Override
protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Model msg) throws Exception {
//3.1 根据类型输出收到的客户端的信息
DataInfo.Model.ModelType dataType = msg.getDataType();
switch (dataType){
case StudentType:
DataInfo.Student student = msg.getStudent();
System.out.println("id:"+student.getId()+" name:"+student.getName()+" email:"+student.getEmail());
break;
case WorkerType:
DataInfo.Worker worker = msg.getWorker();
System.out.println("id:"+worker.getId()+" name:"+worker.getName()+" age:"+worker.getAge());
}
//3.2 给客户端回复worker类型的信息
DataInfo.Model worker = DataInfo.Model.newBuilder()
.setDataType(DataInfo.Model.ModelType.WorkerType)
.setWorker(
DataInfo.Worker.newBuilder()
.setId(1)
.setName("worker")
.setAge(30)
.build())
.build();
ctx.writeAndFlush(worker);
}
});
}
});
ChannelFuture channelFuture = serverBootstrap.bind(9999).sync();
channelFuture.addListener(future -> {
if (future.isSuccess())
System.out.println("ok");
else
System.out.println("no");
});
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}