可以在 proto 中定义多个类,然后从中选择任意一个类,可以在 proto 中定义多个 message,然后再将多个 message 以枚举的形式供使用时选择。
MyMessage.proto
syntax = "proto2" ;
package netty.protobuf.diff ;
option optimize_for = SPEED ;
option java_package = "netty.protobuf.diff" ;
option java_outer_classname = "MyMessage" ;
message MessageData
{
enum MessageType {
PersonType = 1 ;
DogType = 2 ;
}
required MessageType Message_Type = 1 ;
oneof messageContent {
PersonData person = 2 ;
DogData dog = 3 ;
}
}
message PersonData {
optional string pname = 1 ;
optional int32 page = 2 ;
}
message DogData {
optional string dname = 1 ;
optional string dcolor = 2 ;
}
MyNettyClientTest
package netty.protobuf.diff;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class MyNettyClientTest {
public static void main(String[] args) {
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new MyNettyClientInitializer());
Channel channel = bootstrap.connect("127.0.0.1", 8888).sync().channel();
} catch (Exception e) {
e.printStackTrace();
} finally {
eventLoopGroup.shutdownGracefully();
}
}
}
MyNettyClientInitializer
package netty.protobuf.diff;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
public class MyNettyClientInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast("ProtobufVarint32FrameDecoder",new ProtobufVarint32FrameDecoder()) ;
pipeline.addLast("ProtobufVarint32LengthFieldPrepender",new ProtobufVarint32LengthFieldPrepender());
// 用于将 MyMessage 类转为字节码
pipeline.addLast("ProtobufEncoder",new ProtobufEncoder());
// 构建 MyMessage 对象,并发送给服务端
pipeline.addLast("MyNettyClientHandler", new MyNettyClientHandler());
}
}
MyNettyClientHandler
package netty.protobuf.diff;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class MyNettyClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String receiveMsg) {
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 如果 num=1,向服务端发送 person对象,否则发送 dog 对象
int num = 1;
MyMessage.MessageData message;
MyMessage.MessageData.Builder messageBuilder = MyMessage.MessageData.newBuilder();
MyMessage.PersonData.Builder personBuilder = MyMessage.PersonData.newBuilder();
MyMessage.DogData.Builder dogBuilder = MyMessage.DogData.newBuilder();
if (num == 1) {
// 构建 person 对象
MyMessage.PersonData person = personBuilder.setPname("zs").setPage(23).build();
message = messageBuilder.setMessageType(MyMessage.MessageData.MessageType.PersonType).setPerson(person).build();
} else {
// 构建 dog 对象
MyMessage.DogData dog = dogBuilder.setDname("wc").setDcolor("red").build();
message = messageBuilder.setMessageType(MyMessage.MessageData.MessageType.DogType).setDog(dog).build();
}
ctx.channel().writeAndFlush(message);
}
}
MyNettyServerTest
package netty.protobuf.diff;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class MyNettyServerTest {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// ServerBootstrap:服务端启动时的初始化操作
ServerBootstrap serverBootstrap = new ServerBootstrap();
// 将bossGroup 和 workerGroup 注册到服务端的 Channel 上,并注册一个服务端的初始化器 NettyServerInitializer
// 该初始化器中的 initChannel() 方法,会在连接被注册后立刻执行;最后将端口号绑定到 8888
ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new MyNettyServerInitializer()).bind(8888).sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
MyNettyServerInitializer
package netty.protobuf.diff;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
public class MyNettyServerInitializer extends ChannelInitializer<SocketChannel> {
protected void initChannel(SocketChannel sc) throws Exception {
ChannelPipeline pipeline = sc.pipeline();
pipeline.addLast("ProtobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder());
// 用于将 byte[] 解码为 MessageData 对象
pipeline.addLast("ProtobufDecoder", new ProtobufDecoder(MyMessage.MessageData.getDefaultInstance()));
pipeline.addLast("ProtobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender());
// MessageData
pipeline.addLast("MyNettyServerHandler", new MyNettyServerHandler());
}
}
MyNettyServerHandler
package netty.protobuf.diff;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
// 注意,此时 SimpleChannelInboundHandler 的泛型是 MessageData 类型
public class MyNettyServerHandler extends SimpleChannelInboundHandler<MyMessage.MessageData> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, MyMessage.MessageData receiveMsg) throws Exception {
MyMessage.MessageData.MessageType messageType = receiveMsg.getMessageType() ;
// 判断
if(messageType == MyMessage.MessageData.MessageType.PersonType){
MyMessage.PersonData person = receiveMsg.getPerson() ;
System.out.println(person.getPname()+"--" + person.getPage());
}else{
MyMessage.DogData dog = receiveMsg.getDog() ;
System.out.println(dog.getDname()+"--" + dog.getDcolor());
}
}
}
zs--23
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/chengqiuming/article/details/125107467
内容来源于网络,如有侵权,请联系作者删除!