2014-05-13 277 views
1

運行Thrift服務器時,有必要處理客戶端意外斷開連接的情況。這可能發生在服務器正在處理RPC時。如果服務器有阻塞調用,這通常用於掛起操作以通知客戶端異步事件,這並不罕見。無論如何,在任何服務器上都可能發生並且確實發生這種情況,並且經常需要清理。Thrift服務器:檢測客戶端斷開連接(C++庫)

幸運的是,Thrift提供了TServerEventHandler類來掛接連接/斷開回調。這用於使用C++庫和命名管道傳輸的先前版本的Thrift(0.8,我相信)。然而,在Thrift 0.9.1中,當客戶端連接時,createContext()和deleteContext()回調都會立即觸發。兩者都不會觸發客戶端斷開連接。有沒有新的方法來檢測客戶端斷開連接?

代碼片段:

//============================================================================ 
//Code snippet where the server is instantiated and started. This may 
//or may not be syntactically correct. 
//The event handler class is derived from TServerEventHandler. 
// 
{ 
    boost::shared_ptr<MyHandler> handler(new MyHandler()); 
    boost::shared_ptr<TProcessor> processor(new MyProcessor(handler)); 
    boost::shared_ptr<TServerTransport> serverTransport(new TPipeServer("MyPipeName")); 
    boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); 
    boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); 

    boost::shared_ptr<TServer> server(new TSimpleServer(processor, transport, tfactory, pfactory)); 
    boost::shared_ptr<SampleEventHandler> EventHandler(new SampleEventHandler()); 

    server->setServerEventHandler(EventHandler); 
    server->serve(); 
} 

//============================================================================ 
//Sample event callbacks triggered by the server when something interesting 
//happens with the client. 
//Create an overload of TServerEventHandler specific to your needs and 
//implement the necessary methods. 
// 
class SampleEventHandler : public server::TServerEventHandler { 
public: 
    SampleEventHandler() : 
     NumClients_(0) //Initialize example member 
    {} 

    //Called before the server begins - 
    //virtual void preServe() {} 

    //createContext may return a user-defined context to aid in cleaning 
    //up client connections upon disconnection. This example dispenses 
    //with contextual information and returns NULL. 
    virtual void* createContext(boost::shared_ptr<protocol::TProtocol> input, boost::shared_ptr<protocol::TProtocol> output) 
    { 
     printf("SampleEventHandler callback: Client connected (total %d)\n", ++NumClients_); 
     return NULL; 
    } 

    //Called when a client has disconnected, either naturally or by error. 
    virtual void deleteContext(void* serverContext, boost::shared_ptr<protocol::TProtocol>input, boost::shared_ptr<protocol::TProtocol>output) 
    { 
     printf("SampleEventHandler callback: Client disconnected (total %d)\n", --NumClients_); 
    } 

    //Called when a client is about to call the processor - 
    //virtual void processContext(void* serverContext, 
    boost::shared_ptr<TTransport> transport) {} 

protected: 
    uint32_t NumClients_; //Example member 
}; 

回答

1

如果的createContext()和deleteContext()都被稱爲在客戶端連接,而不斷開客戶端,這是一個錯誤,應該在舊貨JIRA所造成的問題。

+0

好點。我忘記提到的是,連接客戶端是C#。也許C#命名爲管道傳輸是奇怪的。 – pmont

+0

可能是,命名管道目前有相當稀疏的測試覆蓋率。另外值得注意的是,TServerEventHandler方法可以在一些需要同步諸如NumClients_等資源的多線程服務器中同時調用。 – codeSF

相關問題