通过netty提供Protobuf服务

1、下载安装Protocol Buffer

    >下载地址: http://code.google.com/p/protobuf/
    >需要下载文件: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();
        }
        
    }
}
 
客户端输出=====
大众
粤A 88888
 


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐
  • —软件人才免语言低担保 赴美带薪读研!—



你可能感兴趣的:(netty,protobuf,服务)