生活随笔
收集整理的這篇文章主要介紹了
                                
thrift中TNonblockingServer的简单用法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                             最近在項目中需要把客戶端的一些信息發送到服務器上,聽起來是個很簡單的需求,但是實際考慮下,覺得如果自己手工實現,工作量也不小,而且盡是些繁瑣且無聊的事情,遂考慮用現成的庫來實現。對比了protocol buffer與thrift后,本著偷懶到底的原則,選擇了thrift,因為thrift本身提供了RPC框架,而protocol buffer僅是個序列化的庫而已。
 
 ? ?首先是編譯thrift,這里參考官方說明,需要先裝boost庫,但是如果要使用nonblocking server的話,還要再把libevent庫也裝上。
 
 ? ? thrift提供了三種服務模型,分別是TSimpleServer, TThreadPoolServer和TNonblockingServer,除去第一個一般僅做測試用,后兩個都可以在實際生產中拿來用。在客戶端不多的情況下,可以選用TThreadPoolServer,但是要注意TThreadPoolServer的客戶端只要不從服務器上斷開連接,就會一直占據服務器的一個線程,當服務器線程池所有線程都在被使用時,新到來的客戶端將排在隊列里等待,直到有客戶端斷開連接,使服務器端線程池出現空閑線程方可繼續被提供服務,所以使用這種模型時,一定要注意客戶端不使用時不要長時間連接服務器,如果確實有這種需求,請使用TNonblockingServer。
 
 
 ? ? 說實話,單純從代碼量上來講,使用Nonblocking server并不比ThreadPool server多了多少,誰讓代碼都是由thrift程序生成的,用戶只需填上實際處理的代碼即可。
 
 ? ? 下面用一個簡單的例子說明
 
 ? ? clientInfo.thrift
 
 
 
   [plain]?view plain
?copy      namespace?cpp?vnmp?? ?? enum?ClientType?{?? ????DOM_MANAGER,?? ????DOM_SERVICE?? }?? ?? enum?RegistResult?{?? ????SUCCESS,?? ????NAME_EXISTED,?? ????INVALIE_PARA,?? }?? ?? struct?ClientInfo?{?? ????1:?string?name,?? ????2:?string?realIP,?? ????3:?string?vpnIP,?? ????4:?ClientType?type,?? ????5:?optional?string?description,?? }?? ?? ?? service?Regist?{?? ????RegistResult?registClient(1:ClientInfo?clientInfo),?? ????bool?heartbeat(1:string?name,?2:ClientType?type)?? }?? 
 
對這個文件做一個簡單的說明,client需要把自己的信息ClientInfo發送到server上注冊,調用registClient方法,heartbeat方法是用來做心跳的。 
 
 
 執行 thrift -r --gen cpp clientInfo.thrift
 
 如果沒有語法錯誤的話,在gen-cpp目錄下會生成 ?
 
 clientInfo_constants.h clientInfo_constants.cpp?
 
 clientInfo_types.h clientInfo_types.cpp
 
 Regist_server.skeleton.cpp
 
 其中的skeleton文件包含了一個簡單的TSimpleServer實現,是可以直接編譯使用的,這個文件也就是我們要修改的文件,建議另外建一個main文件,并將其中內容拷過來,其他幾個強烈建議不要做修改,一來沒需要,二來如果做了修改,下次執行thrift文件時,也會被新生成的文件覆蓋,這也是我前面建議另外建一個main文件還不是直接修改skeketon文件的原因。
 
 下面是main文件的主要內容,略去了頭文件的包含和命名空間的使用等等,這里假定讀者已有了一定的boost基礎。
 
 
 
   [cpp]?view plain
?copy      class?RegistHandler?:?virtual?public?RegistIf?{?? public:?? ?? ????RegistHandler()?{?? ?????????? ????}?? ?? ????RegistResult::type?registClient(const?ClientInfo&?clientInfo)?{?? ?????????? ????????printf("registClient\n");?? ????}?? ?? ????void?heartbeat(const?std::string&?name,?const?ClientType::type?type)?{?? ?????????? ????????printf("heartbeat\n");?? ????}?? ?? };?? ?? int?main(int?argc,?char?**argv)?{?? ????int?port?=?9090;?? ????shared_ptr<RegistHandler>?handler(new?RegistHandler());?? ????shared_ptr<TProcessor>?processor(new?RegistProcessor(handler));?? ????shared_ptr<TProtocolFactory>?protocolFactory(new?TBinaryProtocolFactory());?? ????shared_ptr<ThreadManager>?threadManager?=?ThreadManager::newSimpleThreadManager(15);?? ????shared_ptr<PosixThreadFactory>?threadFactory?=?shared_ptr<PosixThreadFactory?>?(new?PosixThreadFactory());?? ????threadManager->threadFactory(threadFactory);?? ????threadManager->start();?? ????TNonblockingServer?server(processor,?protocolFactory,?port,?threadManager);?? ????server.serve();?? ????return?0;?? }?? 
 
 
regist service的實際處理方法寫在registHandler對應的方法里。主要是main方法做個簡單說明: 
 
 
 這里使用了thrift庫自帶的ThreadManager,建立了一個擁有15個線程的線程池,也就是說這個NonblockingServer擁有15個工作線程。
 
 除了shared_ptr來自boost,其他均是thrift自帶,命名空間是apache::thrift?
 
 client端
 
 
 
   [cpp]?view plain
?copy      int?main(int?argc,?char**?argv)?{?? ????boost::shared_ptr<TSocket>?socket(new?TSocket("localhost",?9090));?? ????boost::shared_ptr<TTransport>?transport(new?TFramedTransport(socket));?? ????boost::shared_ptr<TProtocol>?protocol(new?TBinaryProtocol(transport));?? ?? ????RegistClient?client(protocol);?? ?? ????transport->open();?? ?????? ?????? ????transport->close();?? ????return?0;?? }?? 
 
 
注意對于nonblocking server,client端的TTransport只能選用TFramedTransport;如果通信過程中出現異常,會拋出異常,可以用try catch捕獲并做處理。
                            總結
                            
                                以上是生活随笔為你收集整理的thrift中TNonblockingServer的简单用法的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。