프로 토 콜 버퍼 학습 노트(Java&NodeJS)

Protocol Buffer 가 뭐 예요?
Protocol Buffers(protobuf 라 고도 함)는 Google 회사 가 개발 하 는 언어 에 독립 되 고 플랫폼 에 독립 된 확장 가능 한 구조 화 된 데이터 시퀀스 체제 입 니 다.쉽게 말 하면 xml 과 json 과 같은 부류 입 니 다.데이터 인 터 랙 션 형식 프로 토 콜 입 니 다.주요 장점 은 이 진 을 기반 으로 하기 때문에 구조 화 된 xml 프로 토 콜 에 비해 부피 가 적 고 데 이 터 는 전송 과정 에서 더욱 빠르다 는 것 이다.또한 c++,자바,python,phop,자바 script 등 주류 개발 언어 도 지원 합 니 다.
홈 페이지 주소:https://developers.google.com/protocol-buffers/
Proto 3 설치
다운로드 주소:3.x.x 버 전 은 기본적으로 운영 체제 와 언어 에 따라 구분 되 었 으 며,시스템 패키지 에는 protoc 명령 만 포함 되 어 있 으 며,언어 패 키 지 는 컴 파일 후 사용 되 며,예 를 들 어 자바 는 대응 하 는 jar 패 키 지 를 생 성 해 야 합 니 다.여 기 는 필요 에 따라 해당 하 는 운영 체제 와 언어 패 키 지 를 다운로드 할 수 있 습 니 다.예 를 들 어 여기 서 제 가 다운로드 한 것 은 protoc-3.5.1-osx-x86 입 니 다.64.zip(애플 시스템)과 protobuf-java-3.5.1.tar.gz(자바 언어).
  • unzip protoc-3.5.1-osx-x86_64.zip
  • /etc/profile 에 환경 변수 추가 PROTOCTLBUFFER_HOME(protoc-3.5.1-osx-x86_64.zip 압축 해제 후 디 렉 터 리),PATH 에$PROTOCTL 추가BUFFER_HOME/bin
  • 보기 버 전:protoc --version:출력 libprotoc 3.5.1
  • jar , maven
  • tar -zxcf protobuf-java-3.5.1.tar.gz압축 해제 후 디 렉 터 리 이름 은 protobuf-3.5.1
  • 입 니 다.
  • cd protobuf-3.5.1/src,소프트 연결 만 들 기ln -s $PROTOCTL_BUFFER_HOME/bin/protoc protoc
  • cd protobuf-3.5.1/java,mvn package(maven 은 자체 설치 하 십시오)성공 하면 protobuf-3.5.1/java/code/target 에서 protobuf-java-3.5.1.jar
  • 를 생 성 합 니 다.
  • 그리고 protobuf-java-3.5.1.jar 를 maven 사복 에 올 리 거나 로 컬 창고 에 설치 하면 사용 할 수 있 습 니 다
  • mvn install:install-file -Dfile=protobuf-java-3.5.1.jar -DgroupId=com.google.protobuf -DartifactId=protobuf-java -Dversion=3.5.1 -Dpackaging=jar
    
  • pom 에 의존 추가
  • 
    
        com.google.protobuf
        protobuf-java
        3.5.1
    
    

    Proto 2 설치
    다운로드 주소:여 기 는 운영 체제 패키지 일 뿐 입 니 다.예 를 들 어 여기 서 제 가 다운로드 한 것 은 protoc-2.6.1-osx-x86 입 니 다.64.exe,언어 패키지 protobuf-2.6.1.tar.gz.
  • mv protoc-2.6.1-osx-x86_64.exe protoc
  • 위 에서 이름 을 바 꾼 protoc 파일 이 있 는 디 렉 터 리 를 시스템 환경 변수 PATH 에 추가 합 니 다
  • 보기 버 전:protoc --version:출력 libprotoc 2.6.1
  • jar , maven
  • tar -zxcf protobuf-2.6.1.tar.gz압축 해제 후 디 렉 터 리 이름 은 protobuf-2.6.1
  • 입 니 다.
  • cd protobuf-2.6.1/src,소프트 연결 만 들 기ln -s $PROTOCTL_BUFFER_HOME/bin/protoc protoc
  • cd protobuf-2.6.1/java,mvn package(maven 은 자체 설치 하 십시오)성공 하면 protobuf-2.6.1/java/target 에서 protobuf-java-2.6.1.jar
  • 를 생 성 합 니 다.
  • 그리고 protobuf-java-2.6.1.jar 를 maven 사복 에 올 리 거나 로 컬 창고 에 설치 하면 사용 할 수 있 습 니 다
  • mvn install:install-file -Dfile=protobuf-java-2.6.1.jar -DgroupId=com.google.protobuf -DartifactId=protobuf-java -Dversion=2.6.1 -Dpackaging=jar
    
  • pom 에 의존 추가
  • 
    
        com.google.protobuf
        protobuf-java
        2.6.1
    
    

    Proto 사용
  • 먼저 proto 파일 을 작성 합 니 다.구체 적 인 문법 은 통신 프로 토 콜 의 Protocol buffer(Java 편)
  • 를 참고 하 십시오.
  • 자바 파일 생 성:protoc --java_out=. XXXX.proto
  • js 파일 생 성:protoc --js_out=import_style=commonjs,binary:. XXXX.proto"proto 3 만 이 명령 을 지원 합 니 다"
  • proto 2 는 proto 3 문법 과 약간 다 르 지만 사용 할 때 특별한 차이 점 이 없습니다.또한 proto 3 는 proto 2 를 아래로 호 환 하기 때문에 proto 3 만 설치 한 다음 에 proto 파일 에서'syntax='proto 2'를 설명 할 수 있 습 니 다.또는 구문="proto 3";"형식 지정
  • proto 예
    //syntax = "proto2";
    package com.data.upload.proto;
    
    // 4.1              
    message BaseInfoCompany
    {
        //     
        required string CompanyId       = 1;
    
        //     
        required string CompanyName     = 2;
    
        //         
        required string Identifier      = 3;
    
        //          
        required uint32 Address         = 4;
    
        //     
        required string BusinessScope   = 5;
    
        //     
        required string ContactAddress  = 6;
    
        //         
        required string EconomicType    = 7;
    
        //     
        required string RegCapital      = 8;
    
        //       
        required string LegalName       = 9;
    
        //         
        required string LegalID         = 10;
    
        //       
        required string LegalPhone      = 11;
    
        //               
        optional string LegalPhoto      = 12;
    
        //   
        required uint32 State           = 13;
    
        //     
        required uint32 Flag            = 14;
    
        //     
        required uint64 UpdateTime      = 15;
    
        //     
        optional string Reserved        = 16;
    }
    
    // 4.2                  
    message BaseInfoCompanyStat
    {
        //     
        required string CompanyId       = 1;
    
        //          
        required uint32 VehicleNum      = 2;
    
        //         
        required uint32 DriverNum       = 3;
    
        //     
        required uint32 Flag            = 4;
    
        //     
        required uint64 UpdateTime      = 5;
    
        //     
        optional string Reserved        = 6;
    }
    
    enum IpcType
    {
        // 4.1              
        baseInfoCompany                             = 0x1001;
    
        // 4.2                  
        baseInfoCompanyStat                         = 0x1002;
    }
    
    message OTIpc
    {
         //     
         required string CompanyId                                  = 1;
    
         //       
         required string Source                                     = 2;
    
         //       
         required IpcType IPCType                                   = 3;
    
        // 4.1              
        repeated BaseInfoCompany baseInfoCompany                    = 0x1001;
    
        // 4.2                  
        repeated BaseInfoCompanyStat baseInfoCompanyStat            = 0x1002;
    }
    
    message OTIpcList
    {
         repeated OTIpc otpic                     = 1;
    }  
    
    

    java 에서 Protocol Buffer 사용 하기
  • 의존 추가
  • 
    
        com.google.protobuf
        protobuf-java
        2.6.1
    
    
  • 클 라 이언 트 엔 드
  •   //    
      OTIpcDef.BaseInfoCompany.Builder baseInfoCompanyBuilder = OTIpcDef.BaseInfoCompany.newBuilder();
      baseInfoCompanyBuilder.setAddress(110011);
      baseInfoCompanyBuilder.setCompanyId("companyId");
      baseInfoCompanyBuilder.setCompanyName("companyName");
      baseInfoCompanyBuilder.setIdentifier("identifier");
      baseInfoCompanyBuilder.setBusinessScope("BusinessScope");
      baseInfoCompanyBuilder.setContactAddress("ContactAddress");
      baseInfoCompanyBuilder.setEconomicType("EconomicType");
      baseInfoCompanyBuilder.setRegCapital("RegCapital");
      baseInfoCompanyBuilder.setLegalName("LegalName");
      baseInfoCompanyBuilder.setLegalID("LegalID");
      baseInfoCompanyBuilder.setLegalPhone("LegalPhone");
      baseInfoCompanyBuilder.setState(0);
      baseInfoCompanyBuilder.setFlag(1);
      baseInfoCompanyBuilder.setUpdateTime(20180226121212l);
    
      OTIpcDef.BaseInfoCompany baseInfoCompany = baseInfoCompanyBuilder.build();
    
      OTIpcDef.OTIpc.Builder otIpcBuilder = OTIpcDef.OTIpc.newBuilder();
      otIpcBuilder.setCompanyId("companyId");
      otIpcBuilder.setSource("Source");
      otIpcBuilder.setIPCType(OTIpcDef.IpcType.baseInfoCompany);
    
      //              list
      //List list  = new ArrayList();
      //list.add(baseInfoCompany);
      //otIpcBuilder.addAllBaseInfoCompany(list);
    
      //    add         
      otIpcBuilder.addBaseInfoCompany(baseInfoCompany);
      otIpcBuilder.addBaseInfoCompany(baseInfoCompany);
    
      OTIpcDef.OTIpc otIpc = otIpcBuilder.build();
    
      OTIpcDef.BaseInfoCompanyStat.Builder baseInfoCompanyStatBuilder = OTIpcDef.BaseInfoCompanyStat.newBuilder();
      baseInfoCompanyStatBuilder.setCompanyId("companyId");
      baseInfoCompanyStatBuilder.setDriverNum(10);
      baseInfoCompanyStatBuilder.setFlag(0);
      baseInfoCompanyStatBuilder.setUpdateTime(20180226121212l);
      baseInfoCompanyStatBuilder.setVehicleNum(5);
    
      OTIpcDef.BaseInfoCompanyStat baseInfoCompanyStat = baseInfoCompanyStatBuilder.build();
    
      OTIpcDef.OTIpc.Builder otIpcBuilder2 = OTIpcDef.OTIpc.newBuilder();
      otIpcBuilder2.setCompanyId("companyId");
      otIpcBuilder2.setSource("Source");
      otIpcBuilder2.setIPCType(OTIpcDef.IpcType.baseInfoCompanyStat);
    
      otIpcBuilder2.addBaseInfoCompanyStat(baseInfoCompanyStat);
    
      OTIpcDef.OTIpc otIpc2 = otIpcBuilder2.build();
    
      OTIpcDef.OTIpcList.Builder oTIpcListBuilder = OTIpcDef.OTIpcList.newBuilder();
      oTIpcListBuilder.addOtpic(otIpc);
      oTIpcListBuilder.addOtpic(otIpc2);
    
      OTIpcDef.OTIpcList otIpcList = oTIpcListBuilder.build();
      //     
      byte[] array = otIpcList.toByteArray();
    
      HttpClientUtils httpClientUtils = new HttpClientUtils();
      httpClientUtils.doPost4ProtocleBuffer("http://localhost:3000/demo/protoc",array);
    

    HttpClientUtils.java
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.ByteArrayEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.client.LaxRedirectStrategy;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.util.EntityUtils;
    
    public class HttpClientUtils {
    
        private CloseableHttpClient httpClient;
    
        private RequestConfig requestConfig;
    
        public HttpClientUtils(){
            init();
        }
    
    
        public void init(){
    
            PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
            //      requestConfig
            this.requestConfig = RequestConfig.custom().build();
            //          
            LaxRedirectStrategy redirectStrategy = new LaxRedirectStrategy();
    
            this.httpClient = HttpClients.custom().setConnectionManager(httpClientConnectionManager)
                    .setDefaultRequestConfig(requestConfig)
                    .setRedirectStrategy(redirectStrategy)
                    .build();
        }
    
        public void doPost4ProtocleBuffer(String url, byte[] bytes) throws Exception {
    
    
            //   http POST  
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(this.requestConfig);
            httpPost.setHeader("Connection", "keep-alive");
            httpPost.setHeader("Content-type", "application/x-protobuf");
            httpPost.setHeader("Accept-Encoding", "gzip");
            httpPost.setHeader("Accept-Charset", "utf-8");
    
            if (bytes != null) {
                //         
                ByteArrayEntity byteArrayEntity = new ByteArrayEntity(bytes);
                byteArrayEntity.setContentType("application/x-protobuf");
                //         httpPost   
                httpPost.setEntity(byteArrayEntity);
            }
            CloseableHttpResponse response = null;
            try {
                //     
                response = this.httpClient.execute(httpPost);
               
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        }
    }
    
  • 서버 엔 드
  • InputStream in = request.getInputStream();
    OTIpcDef.OTIpcList otIpcList = OTIpcDef.OTIpcList.parseFrom(in);
    List list= otIpcList.getOtpicList();
    for(OTIpcDef.OTIpc otIpc : list){
        String companyid = otIpc.getCompanyId();
        String source = otIpc.getSource();
        OTIpcDef.IpcType ipcType = otIpc.getIPCType();
        if(ipcType == OTIpcDef.IpcType.baseInfoCompany){
            List baseInfoCompanyList = otIpc.getBaseInfoCompanyList();
            for(OTIpcDef.BaseInfoCompany baseInfoCompany : baseInfoCompanyList){
                String companyName = baseInfoCompany.getCompanyName();
            }
        }else if(ipcType == OTIpcDef.IpcType.baseInfoCompanyStat){
            List baseInfoCompanyStatList = otIpc.getBaseInfoCompanyStatList();
            for(OTIpcDef.BaseInfoCompanyStat baseInfoCompanyStat : baseInfoCompanyStatList){
                int driverNum = baseInfoCompanyStat.getDriverNum();
            }
        }
    }
    

    nodejs 에서 Protocol Buffer 사용 하기
  • 설치 의존npm install google-protobuf --savenpm install bufferhelper --save
  • 클 라 이언 트 엔 드
  • var OTIpcDefProto = require('../protocbuf/OTIpcDef_pb');
    var http = require('http');
    
    //      
    var baseInfoCompany = new OTIpcDefProto.BaseInfoCompany();
    baseInfoCompany.setAddress(110011);
    baseInfoCompany.setCompanyid("companyId");
    baseInfoCompany.setIdentifier("identifier");
    baseInfoCompany.setCompanyname("companyName    ");
    baseInfoCompany.setBusinessscope("BusinessScope");
    baseInfoCompany.setContactaddress("ContactAddress");
    baseInfoCompany.setEconomictype("EconomicType");
    baseInfoCompany.setRegcapital("RegCapital");
    baseInfoCompany.setLegalname("LegalName");
    baseInfoCompany.setLegalid("LegalID");
    baseInfoCompany.setLegalphone("LegalPhone");
    baseInfoCompany.setState(0);
    baseInfoCompany.setFlag(1);
    baseInfoCompany.setUpdatetime(20180226121212);
    
    //      
    var otIpc = new OTIpcDefProto.OTIpc();
    otIpc.setCompanyid("companyId");
    otIpc.setSource("Source");
    otIpc.setIpctype(OTIpcDefProto.IpcType.BASEINFOCOMPANY);
    //      add            
    otIpc.addBaseinfocompany(baseInfoCompany);
    
    //     list  
    var otIpcList = new OTIpcDefProto.OTIpcList();
    //    add            
    otIpcList.addOtpic(otIpc);
    
    //     
    var contents = otIpcList.serializeBinary();
    
    
    var options = {
        host: 'localhost',
        port: 3000,
        path: '/demo2/protoc',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-protobuf'
        }
    };
    
    //    
    var req = http.request(options, function(res){
        // res.setEncoding('uft8');
        res.on('data', function(data){
            console.log(data);
        });
    });
    
    //  buffer
    var buffer = new Buffer(contents);
    //   string buffer  
    req.write(buffer);
    req.end();
    
  • 서버 엔 드(express)
  • var express = require('express');
    var router = express.Router();
    var OTIpcDefProto = require('../protocbuf/OTIpcDef_pb');
    var BufferHelper = require('bufferhelper');
    
    
    // http://localhost:3000/demo/
    router.post('/protoc', function(req, res, next) {
        //    ,    bufferHelper  protocolbuffer  
        var bufferHelper = new BufferHelper();
        req.on("data", function (chunk) {
            bufferHelper.concat(chunk);
        });
        req.on('end', function () {
            var buffer = bufferHelper.toBuffer();
            //buffer   proto  
            var otIpcList = OTIpcDefProto.OTIpcList.deserializeBinary(new Uint8Array(buffer));
    
            for(var i=0;i

    protocolbuffer 데이터 의 수신 과정 을 app.js 에 밀봉 할 수 있 습 니 다.
    //                ,        
    app.use('/*',function(req, res, next) {
    
      var contentType = req.get('Content-Type');
      //  contentType,   protobuf         req.body 
      if(contentType=='application/x-protobuf') {
          var bufferHelper = new BufferHelper();
          req.on("data", function (chunk) {
              bufferHelper.concat(chunk);
          });
          req.on('end', function () {
              var buffer = bufferHelper.toBuffer();
              req.body = buffer;
              console.log(req.body);
              next();
          });
      }else{
          next();
      }
    
    });
    

    그리고 경로 js 에서 다음 과 같은 방식 으로 데 이 터 를 받 으 면 됩 니 다.
    var otIpcList = OTIpcDefProto.OTIpcList.deserializeBinary(new Uint8Array(req.body));
    
  • 서버 엔 드(restify)restify 에서 proto 데 이 터 를 받 는 것 은 간단 합 니 다.proto 데이터 가 req.body 에 봉 인 됐 기 때문에 사용 방식 은 위의 express 와 유사 한 두 번 째 방법
  • 입 니 다.
    var otIpcList = OTIpcDefProto.OTIpcList.deserializeBinary(new Uint8Array(req.body));
    

    JSON 과 Protobuf 의 상호 전환
    JAVA
    
    
        com.googlecode.protobuf-java-format
        protobuf-java-format
        1.4
    
    
  • json to proto
  • com.googlecode.protobuf.format.JsonFormat jsonFormat = new JsonFormat();
    com.google.protobuf.Message.Builder builder = OTIpcDef.BaseInfoCompany.newBuilder();
    //           json   ,      json           
    String json = com.alibaba.fastjson.JSON.toJSONString(myObject);
    //     json  builder           merge,                     ,                    ,     builder           。
    jsonFormat.merge(new ByteArrayInputStream(json.getBytes()), builder);     
    
  • proto to json
  • OTIpcDef.OTIpcList otIpcList = oTIpcListBuilder.build();
    //proto   json
    com.googlecode.protobuf.format.JsonFormat jsonFormat = new JsonFormat();
    String json =jsonFormat.printToString(otIpcList);
    

    nodejs
  • json to proto 는 json 2 Proto.js 를 작성 합 니 다.json 문자열 을 봉 인 된 proto 대상 으로 변환 하 는 방법
  • var json2proto = function (json_str,protoObject) {
        Array.prototype.contains = function ( needle ) {
            for (i in this) {
                if (this[i] == needle) return true;
            }
            return false;
        }
        var p_json_str = json_str;
        var p_json = eval("(" + p_json_str + ")");
        var p_json_key_array = [];
        var i = 0;
        for(var p in p_json){//  json     key/value ,p key
            p_json_key_array[i] = p;
            i++;
        }
        var s_json = protoObject.toObject();
        for(var p in s_json){//  json     key/value ,p key
            if (p_json_key_array.contains(p)) {
                var setMethod = "set"+p.charAt(0).toUpperCase() + p.slice(1);
                protoObject[setMethod](p_json[p]);
            }
        }
        return protoObject;
    }
    module.exports = json2proto;
    

    호출 방법
    var OTIpcDefProto = require('../protocbuf/OTIpcDef_pb');
    var json2proto = require('../json2Proto');
    //json   
    var p_json_str = "{ companyid: '  ID'," +
        "companyname: 'companyId'," +
        "identifier : 'identifier'," +
        "address : 111111," +
        "businessscope : 'businessscope'," +
        "contactaddress : 'contactaddress'," +
        "economictype : 'economictype'," +
        "regcapital : 'regcapital'," +
        "legalname : 'legalname'," +
        "legalid : 'legalid'," +
        "legalphone : 'legalphone'," +
        "legalphoto : 'legalphoto'," +
        "state : 0," +
        "flag : 1," +
        "updatetime: 20180226121212}";
    var baseInfoCompany = json2proto(p_json_str,new OTIpcDefProto.BaseInfoCompany());
    
    console.log(baseInfoCompany.toObject());
    

    좋은 웹페이지 즐겨찾기