【问题标题】:Thrift server: detect client disconnections (C++ library)Thrift 服务器:检测客户端断开连接(C++ 库)
【发布时间】:2014-07-01 17:06:15
【问题描述】:

运行 Thrift 服务器时,有必要处理客户端意外断开连接的情况。这可能在服务器处理 RPC 时发生。如果服务器有一个阻塞调用,该调用通常用于挂起操作以通知客户端异步事件,则这种情况并不少见。在任何情况下,这都是在任何服务器上都可能发生并且确实发生的极端情况,并且通常需要进行清理。

幸运的是 Thrift 提供了 TServerEventHandler 类来挂钩连接/断开回调。这曾经在 Thrift 的早期版本(我相信是 0.8)中使用 C++ 库和命名管道传输。然而,在 Thrift 0.9.1 中,createContext() 和 deleteContext() 回调都会在客户端连接时立即触发。不再在客户端断开连接时触发。有没有检测客户端断开连接的新方法?

代码sn-p:

//============================================================================
//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++ client-server thrift thrift-protocol


    【解决方案1】:

    如果在客户端连接时同时调用 createContext() 和 deleteContext() 而客户端没有断开连接,这是一个错误,应该在 Thrift jira 中创建一个问题。

    【讨论】:

    • 好点。我忘了提到的是连接客户端是 C#。也许 C# 命名管道传输的行为很奇怪。
    • 可能是,命名管道目前的测试覆盖率非常低。另外值得注意的是,TServerEventHandler 方法可以在一些需要同步读写资源(如 NumClients_)的多线程服务器中并发调用。
    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    相关资源
    最近更新 更多