zoukankan      html  css  js  c++  java
  • Thrift安装编译指南

    前言:thrift的版本问题比较麻烦,高版本的在c++上需要c++ 11的支持,而低版本则可能在go的支持上有问题,测试发现thrift 9.0以上需要c++ 11,而thrift 8.0则在go的支持上可能会存在问题。使用的发行版本是centos 6.5,gcc 4.4.7。最终选择使用thrift-0.8.0来编译安装。

    一. 编译安装

    wget http://archive.apache.org/dist/thrift/0.8.0/thrift-0.8.0.tar.gz
    
    tar -zxvf thrift-0.8.0.tar.gz
    cd thrift-0.11.0
    ./configure   #这一步配置可以选择支持的语言,如python,c++,go等。可以./configure --help来查看可配置项。如./configure --without-go
    make && make install 
    
    

    注意:在执行完configure后,会显示实际上支持的库,比如

    thrift 0.11.0	
    Building C (GLib) Library .... : no
    Building C# (Mono) Library ... : no
    Building C++ Library ......... : yes
    Building D Library ........... : no
    Building Dart Library ........ : no
    Building dotnetcore Library .. : no
    Building Erlang Library ...... : no
    Building Go Library .......... : no
    Building Haskell Library ..... : no
    Building Haxe Library ........ : no
    Building Java Library ........ : no
    Building Lua Library ......... : no
    Building NodeJS Library ...... : no
    Building Perl Library ........ : no
    Building PHP Library ......... : no
    Building Plugin Support ...... : no
    Building Python Library ...... : yes
    Building Py3 Library ......... : yes
    Building Ruby Library ........ : no
    Building Rust Library ........ : no
    

    如果编译没问题,那么就可以查看一下版本thrift -version,如果能显示,那么就ok。

    二. 测试使用

    安装完后要搞一个小程序测试一下。thrift的使用是从.thirft文件开始的。
    安装完后,自带的tutorial就有小例子,但感觉不够直观,来copy一个试试效果。

    • step 1 编写thrift文件 yang.thrift

      struct Student{
      1: i32 sno,
      2: string sname,
      3: bool ssex,
      4: i16 sage,
      }
      
      service Serv{
           void put(1: Student s),
           i32 icall(1: Student s),
           string scall(1: Student s),
           /*
               string& srcall(1: Student s),
               -----------------------------
               -thrift -r --gen cpp student.thrift
               -error:
               -   [ERROR:/root/test/thrift/student.thrift:12] (last token was '&')
               -   syntax error
               -   [FAILURE:/root/test/thrift/student.thrift:12] Parser error during include pass.
               -----------------------------
           */
           Student stcall(1: Student s),
      }
      
    • step 2 生成源代码

      比如要生成c++代码,就可以 thrift -r --gen cpp yang.thrift。这样就能在目录下生成一个gen-cpp目录,里面生成了多个文件,其中的Serv_server.skeleton.cpp就是服务器端main函数入口文件。--gen后指定生成的语言,yang.thrift就是编写的thrift魔板。

    • step 3 编写客户端代码

      step 2 生成了服务器端的代码框架(也仅仅是个框架),但是客户端的代码就要自己编写了。

      #include "Serv.h"   //这里包含的是服务器端生成的头文件,注意路径
      #include <transport/TSocket.h>
      #include <transport/TBufferTransports.h>
      #include <protocol/TBinaryProtocol.h>
      
      using namespace apache::thrift;
      using namespace apache::thrift::protocol;
      using namespace apache::thrift::transport;
      
      using boost::shared_ptr;
      
      int main(int argc, char **argv)
      {
          boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
          boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
          boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
      
          transport->open();
      
          //调用server服务
          Student s;
          s.sno = 123;
          s.sname = "hao973";
          s.ssex = 1;
          s.sage = 30;
      
          ServClient client(protocol);
          printf("sno=%d sname=%s ssex=%d sage=%d
      ", s.sno, s.sname.c_str(), s.ssex, s.sage);
          //put
          client.put(s);
          //icall scall
          std::string strname = "";
          client.scall(strname, s);
          printf("icall=%d, scall=%s
      ", client.icall(s), strname.c_str());
          //stcall
          client.stcall(stu, s);
          printf("student sno=%d sname=%s ssex=%d sage=%d
      ", stu.sno, stu.sname.c_str(), stu.ssex, stu.sage);
      
          transport->close();
      
          return 0;
      }
      
    • step 4 修改填充服务器端的代码

      这里主要是填充服务的方法实现。在Serv_server.skeleton.cpp文件put中添加printf(“sno=%d sname=%s ssex=%d sage=%d ”, s.sno, s.sname.c_str(), s.ssex, s.sage);。其他几个函数也是如此添加。下面是最后的结果。

      #include "Serv.h"
      #include <thrift/protocol/TBinaryProtocol.h>
      #include <thrift/server/TSimpleServer.h>
      #include <thrift/transport/TServerSocket.h>
      #include <thrift/transport/TBufferTransports.h>
      
      using namespace ::apache::thrift;
      using namespace ::apache::thrift::protocol;
      using namespace ::apache::thrift::transport;
      using namespace ::apache::thrift::server;
      
      using boost::shared_ptr;
      
      class ServHandler : virtual public ServIf {
       public:
        ServHandler() {
          // Your initialization goes here
        }
      
        void put(const Student& s) {
          // Your implementation goes here
          printf("put
      ");
          printf("sno=%d sname=%s ssex=%d sage=%d
      ", s.sno, s.sname.c_str(), s.ssex, s.sage);
        }
      
        int32_t icall(const Student& s) {
          // Your implementation goes here
          printf("icall
      ");
          printf("sno=%d sname=%s ssex=%d sage=%d
      ", s.sno, s.sname.c_str(), s.ssex, s.sage);
          return s.sage;
        }
      
        void scall(std::string& _return, const Student& s) {
          // Your implementation goes here
          printf("scall
      ");
          printf("sno=%d sname=%s ssex=%d sage=%d
      ", s.sno, s.sname.c_str(), s.ssex, s.sage);
          _return = s.sname;
        }
      
        void stcall(Student& stu, const Student& s) {
          // Your implementation goes here
          printf("stcall
      ");
          printf("sno=%d sname=%s ssex=%d sage=%d
      ", s.sno, s.sname.c_str(), s.ssex, s.sage);
          stu.sno     = s.sno + 1;
          stu.sname   = s.sname + "123";
          stu.ssex    = s.ssex;
          stu.sage    = s.sage + 10;
        }
      
      };
      
      int main(int argc, char **argv) {
        int port = 9090;
        shared_ptr<ServHandler> handler(new ServHandler());
        shared_ptr<TProcessor> processor(new ServProcessor(handler));
        shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
        shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
        shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
      
        TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
        server.serve();
        return 0;
      }
      
    • step 5 编译链接

      client 端:
      g++ -DHAVE_NETINET_IN_H -g -Wall -I/usr/local/include/thrift -I/usr/include/boost -I./gen-cpp -I/usr/include Serv.cpp yang_constants.cpp yang_types.cpp client.cpp -L/usr/local/lib/ -lthrift -o client

      这里注意需要 -DHAVE_NETINET_IN_H,否则会报一堆找不到定义。
      然后是 -I./gen-cpp需要跟client.cpp中的头文件相匹配。因为需要服务器端生成的.h文件
      需要指定链接-lthrift库,指定的是载/usr/local/lib中,在运行时中可能会报找不到,需要在/etc/ld.so.conf.d/中弄一个文件,然后ldconfig,更新链接库。
      还有一个很坑的是:client.cpp需要服务器端生成的cpp文件,其中有类中方法的实现,所以编译时需要指明。

      server端:
      g++ -DHAVE_NETINET_IN_H -g -Wall -I/usr/local/include/thrift -I/usr/include/boost -I./ -I/usr/include Serv.cpp Serv_server.skeleton.cpp yang_constants.cpp yang_types.cpp -L/usr/local/lib/*.so -lthrift -o server

    编译完就可以运行,查看效果了!done!

  • 相关阅读:
    在WEB页面中使用Windows Control可行不?
    升级MDMS到2007下啦
    OSS2007与现有系统(asp)如何集成呢
    Directory Class
    P/Invoke能够在ASP.NET中使用吗?
    SPS中的摘要视图下该怎么分页显示信息?
    P/Invoke能够在asp.net 中使用哦
    SVN+AnkhSVN端配置
    利用反射来实现类(含可空字段)的映射
    iis7部署WCF服务应用程序
  • 原文地址:https://www.cnblogs.com/yhp-smarthome/p/8982758.html
Copyright © 2011-2022 走看看