集成步骤:
1、编写 .proto 文件
编写 netty_demo.proto 文件,内容如下
syntax ="proto2";
package com.github.mgljava.protobuf.netty;
option optimize_for = SPEED;
option java_package = "com.github.mgljava.protobuf.netty";
option java_outer_classname="NettyDemoData";
// 请求对象
message RequestUser{
optional string user_name = 1;
optional int32 age = 2;
optional string password = 3;
}
// 响应对象
message ResponseBank{
optional string bank_no = 1;
optional double money = 2;
optional string bank_name=3;
}
2、根据ProtoBuf的工具来生成 Java的实体类: NettyDemoData.java
// 参数介绍:第一个参数src/main/java/ 代表的是要将代码生成后放到哪里,第二个参数src/protobuf/netty_demo.proto是需要告诉 protoc 自定义的 .proto 文件在哪里
protoc --java_out=src/main/java/ src/protobuf/netty_demo.proto
protoc 是ProtoBuf提供的,根据 .proto 文件生成代码的工具,这里使用到了 --java_out 选项,更多选项可以使用 protoc -h
得到。
3、编写Netty的服务端
public class NettyDemoServer {
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 ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ProtobufVarint32FrameDecoder());
// 解码器,将数据解码成 RequestUser 对象
pipeline.addLast(new ProtobufDecoder(NettyDemoData.RequestUser.getDefaultInstance()));
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new NettyDemoServerHandler());
}
});
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class NettyDemoServerHandler extends SimpleChannelInboundHandler<RequestUser> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, RequestUser requestUser) {
System.out.println("姓名:" + requestUser.getUserName());
System.out.println("年龄:" + requestUser.getAge());
System.out.println("密码:" + requestUser.getPassword());
NettyDemoData.ResponseBank response = NettyDemoData.ResponseBank.newBuilder().setBankName("银行")
.setBankNo("123456789987654321").setMoney(100.00).build();
ctx.channel().writeAndFlush(response);
}
}
4、编写Netty的客户端
public class NettyDemoClient {
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 ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ProtobufVarint32FrameDecoder());
// 解码器,将数据解码成 ResponseBank 对象
pipeline.addLast(new ProtobufDecoder(NettyDemoData.ResponseBank.getDefaultInstance()));
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new NettyDemoClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
channelFuture.channel().closeFuture().sync();
} finally {
eventLoopGroup.shutdownGracefully();
}
}
}
public class NettyDemoClientHandler extends SimpleChannelInboundHandler<ResponseBank> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ResponseBank msg) {
System.out.println("账号:" + msg.getBankNo());
System.out.println("名称:" + msg.getBankName());
System.out.println("存款:" + msg.getMoney());
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
NettyDemoData.RequestUser user = NettyDemoData.RequestUser.newBuilder()
.setUserName("张三")
.setAge(20)
.setPassword("123456").build();
ctx.channel().writeAndFlush(user);
}
}
5、测试
服务器端输出:
客户端输出:
在这里插入图片描述
网友评论