日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

thrift中TNonblockingServer的简单用法

發(fā)布時(shí)間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 thrift中TNonblockingServer的简单用法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近在項(xiàng)目中需要把客戶(hù)端的一些信息發(fā)送到服務(wù)器上,聽(tīng)起來(lái)是個(gè)很簡(jiǎn)單的需求,但是實(shí)際考慮下,覺(jué)得如果自己手工實(shí)現(xiàn),工作量也不小,而且盡是些繁瑣且無(wú)聊的事情,遂考慮用現(xiàn)成的庫(kù)來(lái)實(shí)現(xiàn)。對(duì)比了protocol buffer與thrift后,本著偷懶到底的原則,選擇了thrift,因?yàn)閠hrift本身提供了RPC框架,而protocol buffer僅是個(gè)序列化的庫(kù)而已。

? ?首先是編譯thrift,這里參考官方說(shuō)明,需要先裝boost庫(kù),但是如果要使用nonblocking server的話(huà),還要再把libevent庫(kù)也裝上。

? ? thrift提供了三種服務(wù)模型,分別是TSimpleServer, TThreadPoolServer和TNonblockingServer,除去第一個(gè)一般僅做測(cè)試用,后兩個(gè)都可以在實(shí)際生產(chǎn)中拿來(lái)用。在客戶(hù)端不多的情況下,可以選用TThreadPoolServer,但是要注意TThreadPoolServer的客戶(hù)端只要不從服務(wù)器上斷開(kāi)連接,就會(huì)一直占據(jù)服務(wù)器的一個(gè)線(xiàn)程,當(dāng)服務(wù)器線(xiàn)程池所有線(xiàn)程都在被使用時(shí),新到來(lái)的客戶(hù)端將排在隊(duì)列里等待,直到有客戶(hù)端斷開(kāi)連接,使服務(wù)器端線(xiàn)程池出現(xiàn)空閑線(xiàn)程方可繼續(xù)被提供服務(wù),所以使用這種模型時(shí),一定要注意客戶(hù)端不使用時(shí)不要長(zhǎng)時(shí)間連接服務(wù)器,如果確實(shí)有這種需求,請(qǐng)使用TNonblockingServer。

? ? 說(shuō)實(shí)話(huà),單純從代碼量上來(lái)講,使用Nonblocking server并不比ThreadPool server多了多少,誰(shuí)讓代碼都是由thrift程序生成的,用戶(hù)只需填上實(shí)際處理的代碼即可。

? ? 下面用一個(gè)簡(jiǎn)單的例子說(shuō)明

? ? 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)??
  • }??
  • 對(duì)這個(gè)文件做一個(gè)簡(jiǎn)單的說(shuō)明,client需要把自己的信息ClientInfo發(fā)送到server上注冊(cè),調(diào)用registClient方法,heartbeat方法是用來(lái)做心跳的。

    執(zhí)行 thrift -r --gen cpp clientInfo.thrift

    如果沒(méi)有語(yǔ)法錯(cuò)誤的話(huà),在gen-cpp目錄下會(huì)生成 ?

    clientInfo_constants.h clientInfo_constants.cpp?

    clientInfo_types.h clientInfo_types.cpp

    Regist_server.skeleton.cpp

    其中的skeleton文件包含了一個(gè)簡(jiǎn)單的TSimpleServer實(shí)現(xiàn),是可以直接編譯使用的,這個(gè)文件也就是我們要修改的文件,建議另外建一個(gè)main文件,并將其中內(nèi)容拷過(guò)來(lái),其他幾個(gè)強(qiáng)烈建議不要做修改,一來(lái)沒(méi)需要,二來(lái)如果做了修改,下次執(zhí)行thrift文件時(shí),也會(huì)被新生成的文件覆蓋,這也是我前面建議另外建一個(gè)main文件還不是直接修改skeketon文件的原因。

    下面是main文件的主要內(nèi)容,略去了頭文件的包含和命名空間的使用等等,這里假定讀者已有了一定的boost基礎(chǔ)。

    [cpp]?view plain?copy
  • class?RegistHandler?:?virtual?public?RegistIf?{??
  • public:??
  • ??
  • ????RegistHandler()?{??
  • ????????//?Your?initialization?goes?here??
  • ????}??
  • ??
  • ????RegistResult::type?registClient(const?ClientInfo&?clientInfo)?{??
  • ????????//?Your?implementation?goes?here??
  • ????????printf("registClient\n");??
  • ????}??
  • ??
  • ????void?heartbeat(const?std::string&?name,?const?ClientType::type?type)?{??
  • ????????//?Your?implementation?goes?here??
  • ????????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的實(shí)際處理方法寫(xiě)在registHandler對(duì)應(yīng)的方法里。主要是main方法做個(gè)簡(jiǎn)單說(shuō)明:

    這里使用了thrift庫(kù)自帶的ThreadManager,建立了一個(gè)擁有15個(gè)線(xiàn)程的線(xiàn)程池,也就是說(shuō)這個(gè)NonblockingServer擁有15個(gè)工作線(xiàn)程。

    除了shared_ptr來(lái)自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();??
  • ????//insert?your?code?here??
  • ????//??????....??
  • ????transport->close();??
  • ????return?0;??
  • }??

  • 注意對(duì)于nonblocking server,client端的TTransport只能選用TFramedTransport;如果通信過(guò)程中出現(xiàn)異常,會(huì)拋出異常,可以用try catch捕獲并做處理。

    總結(jié)

    以上是生活随笔為你收集整理的thrift中TNonblockingServer的简单用法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。