1、下载安装Protocol Buffer
>需要下载文件:protobuf-2.5.0.tar.gz(也可以直接下载protobuf-java-2.5.0.jar;这里通过maven生成);protoc-2.5.0-win32.zip(windows平台需要)。
>解压protobuf-2.5.0.tar.gz文件,存放在D:\java\protobuf-2.5.0目录下
>解压protoc-2.5.0-win32.zip,得到protoc.exe文件;为了方便使用这里把protoc.exe文件复制到C:\Windows\System32目录下。为了通过maven编译得到jar文件,还需要把protoc.exe复制到D:\java\protobuf-2.5.0\src\目录下。
>打开win终端(运行->cmd),cd D:\java\protobuf-2.5.0\java,mvn package。然后在D:\java\protobuf-2.5.0\java\target\目录下生成protobuf-java-2.5.0.jar文件(用于java工程,也可以通过maven获得)。
---------------------------到此安装完成。
2、编写Protobuf 的proto文件,保存到e:\workPlace\protobuf\目录下。
>简单消息(SimpleMsg.proto)
package protobuf;
option java_package = "com.jan.pr.protobuf";
option java_outer_classname = "SimpleMessage";
message Message{
required int32 id=1;
required string key=2;
required string content=3;
}
>嵌套消息(CarInfoMsg.proto)
option java_package = "com.umpay.pr.protobuf";
option java_outer_classname = "CarInfos";
message Car{
enum CarModel{
BENZ = 0;
VOLKSWAGEN =1;
FORD = 2;
CHEVROLET = 3;
TOYOTA = 4;
Peugeot = 5;
}
enum Sex{
FEMALE = 0;
MALE = 1;
}
message CarOwner{
required string name=1;
required Sex sex = 2 [default = MALE];
required int32 age=3;
required float height=4;
}
message CarInfo{
required string carNumber=11;
required string brand=12;
required string color=13;
required CarModel model = 14 [default=FORD];
required int64 price=15;
required CarOwner owner=16;
}
}
3、生成Java代码
运行命令:protoc.exe --java_out=./ ./CarInfoMsg.proto,会在e:\workPlace\protobuf\目录下生成com这样的目录,找到里面的CarInfos.java文件。
4、Netty服务端(ProtobufNettyServer.java)
package com.umpay.pr.protobuf;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import com.umpay.pr.protobuf.CarInfos.Car.CarInfo;
import com.umpay.pr.protobuf.CarInfos.Car.CarModel;
import com.umpay.pr.protobuf.CarInfos.Car.CarOwner;
import com.umpay.pr.protobuf.CarInfos.Car.Sex;
/**
* desc:Htty服务端
*/
public class ProtobufNettyServer {
public static void main(String[] args) {
ServerBootstrap serverBootstrap = new ServerBootstrap( new NioServerSocketChannelFactory(
Executors.newSingleThreadExecutor(), Executors.newSingleThreadExecutor()));
serverBootstrap.setPipelineFactory( new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("protobufDecoder", new ProtobufVarint32FrameDecoder()); //netty自带的解码器
pipeline.addLast("protobufEncoder", new ProtobufEncoder()); //netty自带的编码器
pipeline.addLast("handler", new ProtobufServerHandler()); //服务handler
return pipeline;
}
});
serverBootstrap.bind( new InetSocketAddress("0.0.0.0",8080));
}
}
/**
* desc:服务handler
*/
class ProtobufServerHandler extends SimpleChannelHandler{
/*
* desc:
* (non-Javadoc)
* @see org.jboss.netty.channel.SimpleChannelHandler#channelConnected(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ChannelStateEvent)
*/
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
CarInfo o = carInfosTrans();
System.out.println("输出~~"+ o.getClass());
ChannelFuture future = e.getChannel().write(o);
future.addListener(ChannelFutureListener.CLOSE);
}
/*
* desc:
* (non-Javadoc)
* @see org.jboss.netty.channel.SimpleChannelHandler#exceptionCaught(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.ExceptionEvent)
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
// super.exceptionCaught(ctx, e);
System.err.println("Unexpected exception from downstream." + e.getCause());
e.getChannel().close();
}
private CarInfo carInfosTrans(){
CarOwner.Builder owner = CarOwner.newBuilder();
owner.setAge(18);
owner.setHeight(170);
owner.setName("jimmy");
owner.setSex(Sex.FEMALE);
CarInfo.Builder carInfo = CarInfo.newBuilder();
carInfo.setBrand("大众");
carInfo.setCarNumber("粤A 88888");
carInfo.setColor("red");
carInfo.setModel(CarModel.VOLKSWAGEN);
carInfo.setPrice(1000);
carInfo.setOwner(owner);
CarInfo carInfoReq = carInfo.build();
// long size = carInfoReq.getSerializedSize();
// byte[] buf = carInfoReq.toByteArray();
return carInfoReq;
}
}
5、Netty客户端代码(ProtobufSocketClient.java)
package com.umpay.pr.protobuf;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import com.umpay.pr.protobuf.CarInfos.Car.CarInfo;
/**
* desc:
* @version V1.0
*/
public class ProtobufSocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 8080);
InputStream in = socket.getInputStream();
CarInfo recCarInfo = CarInfo.parseFrom(in);
System.out.println(recCarInfo.getBrand());
System.out.println(recCarInfo.getCarNumber());
in.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端输出=====