问题
When running a Thrift server, it's necessary to handle cases where the client unexpectedly disconnects. This might happen while the server is processing an RPC. This is not an uncommon occurrence if the server has a blocking call which is often used to pend an operation in order to notify clients of asynchronous events. In any case, it's a corner case that can and does happen on any server and cleanup is often necessary.
Fortunately Thrift provides the class TServerEventHandler to hook into connect/disconnect callbacks. This used to work in prior versions of Thrift (0.8, I believe) using the C++ library and named pipe transport. However in Thrift 0.9.1 the createContext() and deleteContext() callbacks both fire immediately when a client connects. Neither fires on a client disconnect anymore. Is there a new way to detect client disconnects?
Code snippet:
//============================================================================
//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:
If createContext() and deleteContext() are both called at client connect without the client disconnecting, that is a bug and should have an issue created in the Thrift jira.
来源:https://stackoverflow.com/questions/23641170/thrift-server-detect-client-disconnections-c-library