標籤:
Windows下安裝Thrift架構的教程很多。本文的不同之處在於,不藉助Cygwin或者MinGW,只用VS2010,和Thrift官網下載的源檔案,安裝Thrift並使用。
先從官網 下載這兩個檔案:
· thrift-0.9.1.tar.gz
· Thrift compiler for Windows (thrift-0.9.1.exe)
第一個檔案是原始碼包,第二個可執行檔用於在Windows下產生目標語言的樁代碼。
除此以外,還需要boost庫和libevent庫。
安裝Thrift0)準備工作
thrift-0.9.1.tar.gz源碼包
安裝VS2010
安裝boost庫,我使用的boost1.51版本
安裝libevent庫,這裡用的libevent-2.0.21-stable
1)解壓縮thrift-0.9.1.tar.gz
進入\thrift-0.9.1\lib\cpp,VS2010開啟Thrift.sln,有libthrift,libthriftnb兩個工程。
兩個工程的區別是,libthriftnb工程是非阻塞(non-blocking)模式的伺服器,非阻塞模式需要依賴libevent庫。
2)libthrift工程配置:
libthrift>屬性->C/C++->常規->附加元件封裝含目錄->\boost\boost_1_51
libthrift>屬性->庫管理器->常規->附加庫目錄->\boost\boost_1_51\lib
3)libthriftnb工程配置:
libthriftnb>屬性->C/C++->常規->附加元件封裝含目錄->
\boost\boost_1_51
\libevent-2.0.21-stable
\libevent-2.0.21-stable\include
\libevent-2.0.21-stable\WIN32-Code
libthriftnb>屬性->庫管理器->常規->附加庫目錄->
\boost\boost_1_51\lib
4)編譯libthrift和libthriftnb工程
編譯完成後,在\thrift-0.9.1\lib\cpp\Debug下產生libthrift.lib檔案,和libthriftnb.lib檔案。
選擇release模式,則在\thrift-0.9.1\lib\cpp\Release下產生libthrift.lib檔案和libthriftnb.lib檔案。
至此,安裝完成。
開發步驟
安裝好thrift後,就可以開始開發了。開發過程分這麼幾步:
第1步: 寫.thrift檔案,也就是介面描述檔案(Interface Description File);
第2步: 用Thrift compiler for Windows (thrift-0.9.1.exe) ,產生目標語言代碼;
第3步: 伺服器端程式引入thrift產生的程式碼,實現RPC業務代碼。
第4步: 用戶端引入代碼,調用遠程服務。
圖中藍色Thrift.exe就是從官網下載的第二個檔案——“IDL翻譯工具”,協助你把.thrift檔案“翻譯”成目標語言的RPC代碼。
例子
這個例子,遠程Server提供一個函數。用戶端調用這個函數。遠程函數的功能很簡單,就是輸出“Hello Thrift”。
1)寫.thrift檔案
建立文字檔hello.txt,儲存下面的內容後修改副檔名hello.thrift
1 service hello {2 void func1( )3 }2)產生目標語言代碼
把官網下載到的第二個檔案thrift-0.9.1.exe和hello.thrift放到一個目錄(hello)下。
開啟cmd命令列視窗,進入到這個目錄,執行命令:
C:\Users\admin\Desktop\Hello>thrift-0.9.1.exe --gen cpp hello.thrift
執行成功,在hello目錄下,產生一個gen-cpp檔案夾。
3)建立工程
Visual Studio 2010建立win32控制台應用程式。
項目名稱 server
解決方案名稱 hello
注意:附加選項中選擇 勾選 空項目。
類似的,在hello解決方案下,再建立一個空項目client。
4)為項目添加檔案
向Server項目添加檔案。
複製gen-cpp檔案夾中檔案到Server工程,添加到Server工程中。
向Client項目添加檔案。
複製gen-cpp檔案夾中檔案到Client工程,刪除hello_server.skeleton.cpp,並額外添加client.cpp檔案。
最終解決方案的檔案結構是這樣的:
5)設定項目屬性
Sever工程 Server>屬性->C/C++->常規->附加元件封裝含目錄->\boost\boost_1_51
Sever工程 Server>屬性->C/C++->常規->附加元件封裝含目錄->\thrift-0.9.1\lib\cpp\src
Sever工程 Server>屬性->C/C++->常規->附加元件封裝含目錄->\thrift-0.9.1\lib\cpp\src\thrift
Sever工程 Server>屬性->連接器->附加庫目錄->\boost\boost_1_51\lib
Sever工程 Server>屬性->連接器->附加庫目錄->\thrift-0.9.1\lib\cpp\Debug
附加庫目錄指向的是剛剛編譯出的Debug目錄
類似的,Client工程也做這樣的配置。
Client工程 Client>屬性->C/C++->常規->附加元件封裝含目錄->\boost\boost_1_51
Client工程 Client>屬性->C/C++->常規->附加元件封裝含目錄->\thrift-0.9.1\lib\cpp\src
Client工程 Client>屬性->C/C++->常規->附加元件封裝含目錄->\thrift-0.9.1\lib\cpp\src\thrift
Client工程 Client>屬性->連接器->附加庫目錄->\boost\boost_1_51\lib
Client工程 Client>屬性->連接器->附加庫目錄->\thrift-0.9.1\lib\cpp\Debug
6)Client代碼
client.cpp檔案是空的,添加代碼:
1 #include <transport/TSocket.h> 2 #include "hello.h" 3 #include <protocol/TBinaryProtocol.h> 4 #include <server/TSimpleServer.h> 5 #include <transport/TServerSocket.h> 6 #include <transport/TBufferTransports.h> 7 #include <string> 8 #pragma comment(lib, "libthrift.lib") 9 using namespace ::apache::thrift;10 using namespace ::apache::thrift::protocol;11 using namespace ::apache::thrift::transport;12 using namespace ::apache::thrift::server;13 14 using boost::shared_ptr;15 16 #pragma comment(lib,"libthrift.lib")//連結庫檔案17 18 int main(int argc, char** argv) {19 int port = 9090;20 shared_ptr<TTransport> socket(new TSocket("127.0.0.1", 9090));21 shared_ptr<TTransport> transport(new TBufferedTransport(socket));22 shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));23 helloClient client(protocol);24 try{25 transport->open();26 27 client.func1();28 29 transport->close();30 }catch(TException& tx){31 printf("ERROR:%s\n",tx.what());32 }33 getchar();34 return 0;35 }7)Server代碼
hello_server.skeleton.cpp 檔案已經有thrift產生的程式碼,稍作修改,最終如下:
1 // This autogenerated skeleton file illustrates how to build a server. 2 3 // You should copy it to another filename to avoid overwriting it. 4 5 6 7 #include "hello.h" 8 9 #include <thrift/protocol/TBinaryProtocol.h>10 11 #include <thrift/server/TSimpleServer.h>12 13 #include <thrift/transport/TServerSocket.h>14 15 #include <thrift/transport/TBufferTransports.h>16 17 #pragma comment(lib, "libthrift.lib")18 19 using namespace ::apache::thrift;20 21 using namespace ::apache::thrift::protocol;22 23 using namespace ::apache::thrift::transport;24 25 using namespace ::apache::thrift::server;26 27 28 29 using boost::shared_ptr;30 31 32 33 class helloHandler : virtual public helloIf {34 35 public:36 37 helloHandler() {38 39 // Your initialization goes here40 41 }42 43 44 45 void func1() {46 47 // Your implementation goes here48 49 printf("Hello Thrift\n");50 51 }52 53 };54 55 56 57 int main(int argc, char **argv) {58 59 //-----------------------------//60 WORD wVersionRequested;61 62 WSADATA wsaData;63 64 int err;65 66 wVersionRequested =MAKEWORD( 2, 2 );67 68 err = WSAStartup( wVersionRequested, &wsaData );69 //-------------------------------//70 //對上面這段代碼做個說明,這是依賴windows的一段代碼71 //到2014.9.2官網的穩定版0.9.1,仍需要這段代碼才可以在windows下編譯通過。72 //但是如果用git clone最新版,這個錯誤已經修正73 //最新版注釋掉這段代碼,一樣可以在windows下編譯通過。74 //備忘時間:2014.9.275 76 77 int port = 9090;78 79 shared_ptr<helloHandler> handler(new helloHandler());80 81 shared_ptr<TProcessor> processor(new helloProcessor(handler));82 83 shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));84 85 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());86 87 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());88 89 90 91 TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);92 93 server.serve();94 95 return 0;96 97 }8)調試運行
先啟動Server工程,再啟動Client工程。運行結果:
總結
到這裡Thrift的安裝和開發基本操作步驟就介紹完了。Thrift的官方文檔不是很完善,本篇介紹的安裝方法不在網上眾多教程之列,主要區別是沒有使用Cygwin或者MinGW。對於想使用Visual Studio作為開發環境的同學會很有協助。
教程中需要的檔案,都可以從網上擷取,核心代碼在文中已經展示,相信按圖索驥一定可以成功的運行第一個Thrift的例子。
最後十分感謝陳曉蘇(北京)同學,本篇教程整理自他/她名字的一個檔案夾。我從Thrift交流QQ群193713524的共用中獲得的。這裡增加了一些圖片說明和我的理解。最後的例子,做了簡化,是為了直接、清晰的說明安裝過程和開發的配置。
Apache Thrift 在Windows下的安裝與開發