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
};
好點。我忘記提到的是,連接客戶端是C#。也許C#命名爲管道傳輸是奇怪的。 – pmont
可能是,命名管道目前有相當稀疏的測試覆蓋率。另外值得注意的是,TServerEventHandler方法可以在一些需要同步諸如NumClients_等資源的多線程服務器中同時調用。 – codeSF