2014-12-30 56 views
0

我在此刻實現在C基於節儉(0.4.0)服務++獲取客戶端的IP地址與C++和遇到的一個問題:如何節儉

有沒有辦法讓客戶端的IP地址從服務方法實現內部?我正在使用TNonblockingServer。

提前致謝!

回答

0

Ticket THRIFT-1053描述了一個類似的Java請求。該解決方案基本上允許訪問內部(端點)傳輸並從中檢索數據。沒有經過真正的測試,爲C++構建類似的解決方案應該很容易。由於您使用的是Thrift 0.4.0,因此我強烈建議先查看當前中繼(0.9.3)。該TBufferedTransportTFramedTransportTShortReadTransport已經實現了

boost::shared_ptr<TTransport> getUnderlyingTransport(); 

所以上面提到的補丁可能沒有必要在所有。

您的TProcessor派生類在獲取調用process()時獲取兩個傳輸的暫存。如果您覆蓋該方法,你應該能夠管理對數據的訪問,你感興趣的是:

/** 
* A processor is a generic object that acts upon two streams of data, one 
* an input and the other an output. The definition of this object is loose, 
* though the typical case is for some sort of server that either generates 
* responses to an input stream or forwards data from one pipe onto another. 
* 
*/ 
class TProcessor { 
public: 
    // more code 

    virtual bool process(boost::shared_ptr<protocol::TProtocol> in, 
         boost::shared_ptr<protocol::TProtocol> out, 
         void* connectionContext) = 0; 

    // more code 
1

在TNonblockingServer,當TProcessor ::處理()被稱爲TProtocol.transport是TMemoryBuffer,所以aquiring客戶端IP地址是不可能的。

但我們可以擴展類TServerEventHandler方法當客戶端即將調用處理器時,將調用TServerEventHandler :: processContext()。

static boost::thread_specific_ptr<std::string> thrift_client_ip; // thread specific 
class MyServerEventHandler : public TServerEventHandler 
{ 
    virtual void processContext(void* serverContext, boost::shared_ptr<TTransport> transport) 
    { 
     TSocket *sock = static_cast<TSocket *>(transport.get()); 

     if (sock) 
     { 
      //thrift_client_ip.reset(new string(sock->getPeerAddress())); // 0.9.2, reused TNonblockingServer::TConnection return dirty address, see https://issues.apache.org/jira/browse/THRIFT-3270 
      sock->getCachedAddress(); // use this api instead 
     } 
    } 
}; 

// create nonblocking server 
TNonblockingServer server(processor, protocolFactory, port, threadManager); 
boost::shared_ptr<MyServerEventHandler> eventHandler(new MyServerEventHandler()); 
server.setServerEventHandler(eventHandler); 
0
#ifndef NONBLOCK_SERVER_EVENT_HANDLER_H 
#define NONBLOCK_SERVER_EVENT_HANDLER_H 

#include <thrift/transport/TSocket.h> 
#include <thrift/server/TServer.h> 

namespace apache{ 
namespace thrift{ 
namespace server{ 

class ServerEventHandler:public TServerEventHandler{ 
     void* createContext(boost::shared_ptr<TProtocol> input, boost::shared_ptr<TProtocol> output){ 
    (void)input; 
    (void)output; 
    return (void*)(new char[32]);//TODO 
    } 

    virtual void deleteContext(void* serverContext, 
           boost::shared_ptr<TProtocol>input, 
           boost::shared_ptr<TProtocol>output) { 
       delete [](char*)serverContext; 
    } 

    virtual void processContext(void *serverContext, boost::shared_ptr<TTransport> transport){ 
    TSocket *tsocket = static_cast<TSocket*>(transport.get()); 
    if(socket){ 
         struct sockaddr* addrPtr; 
         socklen_t addrLen; 
     addrPtr = tsocket->getCachedAddress(&addrLen); 
        if (addrPtr){ 
             getnameinfo((sockaddr*)addrPtr,addrLen,(char*)serverContext,32,NULL,0,0) ; 
         } 
    } 
    } 
}; 

} 
} 
} 

#endif 

boost::shared_ptr<ServerEventHandler> serverEventHandler(new ServerEventHandler() 
server.setServerEventHandler(serverEventHandler);