【问题标题】:"Tracking" connections with Thrift“跟踪”与 Thrift 的联系
【发布时间】:2011-02-08 01:53:45
【问题描述】:

我正在尝试使用 Thrift 创建游戏,这样客户端就是玩家,服务器管理棋盘,就像 this。但是,我无法弄清楚 Facebook 的 Thrift 服务器如何“跟踪”用户,即在 their service 上调用 attack() 时,我不必再次表明自己的身份。

根据生成的服务器存根提示,没有办法做到这一点:

int main(int argc, char **argv) {
  int port = 9090;
  shared_ptr<ConnectFourHandler> handler(new ConnectFourHandler());
  shared_ptr<TProcessor> processor(new ConnectFourProcessor(handler));
  shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
  shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
  shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

  TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
  server.serve();
  return 0;
}

在该示例中,只为服务器创建了一个处理程序,并且服务器是接受连接的对象。

如果所有请求仅通过每个服务器的一个处理程序路由,Facebook 如何跟踪连接到服务器的客户端?

【问题讨论】:

    标签: c++ rpc thrift


    【解决方案1】:

    试试server.setServerEventHandler。它会在新客户端连接时调用您的代码,让您有机会创建特定于连接的上下文对象。

    【讨论】:

    • serServerEventHandler 到目前为止只有你......除非信息被传递给实际的处理程序(请参阅 OP 中的attack()),如果可能的话,这并不容易
    【解决方案2】:

    因为 thrift 为每个连接使用一个唯一的线程,所以可以使用线程 id 将两者链接在一起。据我所知,节俭本身没有办法做到这一点。如果 thrift 将上下文字段向下传递给每个处理程序函数,Imo 是可能的。

    这是一个使用线程 id 的示例:

    #include <map>
    #include <thread>
    
    typedef struct {
        // you would put your connection specific variables here
    } ConnectionContext;
    
    // You could reverse these types if you had more than one
    // context per thrift connection, eg. your service involved opening
    // or connecting to more than one thing per thrift connection
    std::map<std::thread::id, ConnectionContext> threadContextMap;
    
    class OurEventHandler : public server::TServerEventHandler {
    public:
    OurEventHandler() :
        NumClients_(0)
    {}
    
    //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(shared_ptr<protocol::TProtocol> input, 
    shared_ptr<protocol::TProtocol> output)
    {
        printf("Client connected (total %d)\n", ++NumClients_);
    
        auto this_id = std::this_thread::get_id();
        std::cout << "connected thread " << this_id << std::endl;
    
        return NULL;
    }
    
    //Called when an client has disconnected, either naturally or by error.
    virtual void deleteContext(void* serverContext, 
    shared_ptr<protocol::TProtocol>input, shared_ptr<protocol::TProtocol>output)
    {
        printf("Client disconnected (total %d)\n", --NumClients_);
    
        auto this_id = std::this_thread::get_id();
        std::cout << "disconnected thread " << this_id << std::endl;
    
        auto context = threadContextMap[this_id];
    
        // TODO: Perform your context specific cleanup code here
    }
    
    protected:
        uint32_t NumClients_;
    };
    
    
    class yourRpcHandler : virtual public service_rpcIf
    {
    public:
        yourRpcHandler() :
        {
            // Your initialization goes here
        }
    
        void SomeMethod()
        {
            auto context = threadContextMap[std::this_thread::get_id()];
    
            // TODO: use the context as you see fit
        }
    };
    
    int main(int argc, char **argv)
    {
        int port = 9090;
        printf("Listening on port %d\n", port);
    
        auto rpcHandler = new yourRpcHandler();
        shared_ptr<yourRpcHandler> handler(rpcHandler);
        shared_ptr<TProcessor> processor(new yourRpcProcessor(handler));
        shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
        shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
        shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
    
        TThreadedServer server(processor, serverTransport, transportFactory, protocolFactory);
        shared_ptr<OurEventHandler> EventHandler(new OurEventHandler());
    
        server.setServerEventHandler(EventHandler);
        server.serve();
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      • 2012-02-13
      • 1970-01-01
      • 2011-04-20
      相关资源
      最近更新 更多