3. 配置protobuff编译器的环境变量
4. 阅读protobuff的文档(https://developers.google.com/protocol-buffers/docs/javatutorial)
编写protobuff程序主要有散步
5. protobuff解决的问题
netty集成protobufff完成RPC的方法调用
实现步骤:
1. 进入protobuff需要jar包
2. 编写protobuff的.proto文件(该文件我们也成为idl(interface description language)文件)
syntax = "proto2";
package com.baidu.netty.proto;
option java_package = "com.baidu.netty.sixExample";
option java_outer_classname = "TeacherData";
option optimize_for=SPEED;
message Teacher
{
required int32 id = 1;
optional string name = 2;
enum GenderType
{
MALE = 0;
FEMALE = 1;
}
message Student
{
required int32 id = 1;
optional string name = 2;
optional string email = 3;
optional GenderType gender = 4 [default = MALE];
}
}
3. 使用protobuff的编译器生产代码(几乎所有的RPC框架都有代码生成框架)
protoc --java_out=代码存放的目录 .proto文件存放的位置
4. 简单测试生成的类是否能够使用
package com.baidu.netty.sixExample;
public class TestTearcher {
public static void main(String[] args) throws Exception{
TeacherData.Teacher teacher = TeacherData.Teacher.newBuilder().setId(1).setName("老徐").build();
System.out.println(teacher.getName());
//对象的序列号
byte[] temp = teacher.toByteArray();
//对象的反序列号
TeacherData.Teacher teacher1 = TeacherData.Teacher.parseFrom(temp);
System.out.println(teacher1.getName());
}
}
5. 编写netty的服务器端启动程序
package com.baidu.netty.sixExample;
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 MyServer {
public static void main(String[] args) throws Exception{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new MyServerInitializer());
ChannelFuture future = bootstrap.bind(8899).sync();
future.channel().closeFuture().sync();
}finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
6. 编写服务器端初始化类
package com.baidu.netty.sixExample;
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.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
public class MyServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ProtobufVarint32FrameDecoder());
pipeline.addLast(new ProtobufDecoder(TeacherData.Teacher.getDefaultInstance()));
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new MyServerHandler());
}
}
7. 编写服务器端处理类
package com.baidu.netty.sixExample;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class MyServerHandler extends SimpleChannelInboundHandler<TeacherData.Teacher> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TeacherData.Teacher msg) throws Exception {
System.out.println(msg.getName());
System.out.println(msg.getId());
}
}
8. 编写客户端启动类
package com.baidu.netty.sixExample;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
public class MyClient {
public static void main(String[] args) throws Exception{
EventLoopGroup client = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(client).channel(NioSocketChannel.class).handler(new MyClientInitializer());
ChannelFuture future = bootstrap.connect("localhost",8899).sync();
Channel channel = future.channel();
TeacherData.Teacher teacher = TeacherData.Teacher.newBuilder().setName("老徐").setId(1).build();
channel.writeAndFlush(teacher);
channel.closeFuture().sync();
}finally {
client.shutdownGracefully();
}
}
}
9. 编写客户端初始化类
package com.baidu.netty.sixExample;
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.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
public class MyClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new ProtobufVarint32FrameDecoder());
pipeline.addLast(new ProtobufDecoder(TeacherData.Teacher.getDefaultInstance()));
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast(new ProtobufEncoder());
}
}
10. 测试客户端向服务器端发送对象
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |