Foreword: The version problem of thrift is more troublesome. The higher version needs the support of c++ 11 on C++, while the lower version may have problems with the support of go. The test found that thrift 9.0 and above needs c++ 11, while thrift 8.0 is in go. There may be issues with support. The distribution used is centos 6.5, gcc 4.4.7. Finally choose to use thrift-0.8.0 to compile and install.
1. Compile and install
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
Note: After executing configure, the actual supported libraries will be displayed, such as
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
If there is no problem with the compilation, then you can check the version thrift -version
, if it can be displayed, then it is ok.
2. Test use
After the installation is complete, a small program is required to test it. The use of thrift starts with the .thirft file.
After the installation, the built-in tutorial has a small example, but it doesn't feel intuitive enough, so let's copy a try effect.
step 1 Write the thrift file 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 Generate source code
For example, to generate c++ code, you can
thrift -r --gen cpp yang.thrift
. In this way, a gen-cpp directory can be generated in the directory, and multiple files are generated in it, among whichServ_server.skeleton.cpp
is the server-side main function entry file. Specify the generated language after --gen, yang.thrift is the thrift magic board written.step 3 Write client code
Step 2 generates the server-side code framework (and just a framework), but the client-side code needs to be written by itself.
#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\n", 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\n", client.icall(s), strname.c_str()); //stcall client.stcall(stu, s); printf("student sno=%d sname=%s ssex=%d sage=%d\n", stu.sno, stu.sname.c_str(), stu.ssex, stu.sage); transport->close(); return 0; }
step 4 Modify the code that populates the server side
Here is mainly the method implementation of filling services. Add in the
Serv_server.skeleton.cpp
file putprintf(“sno=%d sname=%s ssex=%d sage=%d\n”, s.sno, s.sname.c_str(), s.ssex, s.sage);
. Several other functions were added as well. Below is the final result.#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\n"); printf("sno=%d sname=%s ssex=%d sage=%d\n", s.sno, s.sname.c_str(), s.ssex, s.sage); } int32_t icall(const Student& s) { // Your implementation goes here printf("icall\n"); printf("sno=%d sname=%s ssex=%d sage=%d\n", 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\n"); printf("sno=%d sname=%s ssex=%d sage=%d\n", 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\n"); printf("sno=%d sname=%s ssex=%d sage=%d\n", 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 Compile and link
client side:
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
Pay attention to the need here
-DHAVE_NETINET_IN_H
, otherwise a bunch of definitions will not be found.
Then it-I./gen-cpp
needs to match the header file in client.cpp. Because the .h file generated by the server
needs to be specified, the link-lthrift library needs to be specified, and the specified is loaded/usr/local/lib
. It may not be found at runtime. You need/etc/ld.so.conf.d/
to get a file in it, then ldconfig, and update the link library.
There is also a pit: client.cpp needs the cpp file generated by the server, which contains the implementation of the methods in the class, so it needs to be specified when compiling.server side:
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
After compiling, you can run it and see the effect! done!