我在此刻實現在C基於節儉(0.4.0)服務++獲取客戶端的IP地址與C++和遇到的一個問題:如何節儉
有沒有辦法讓客戶端的IP地址從服務方法實現內部?我正在使用TNonblockingServer。
提前致謝!
我在此刻實現在C基於節儉(0.4.0)服務++獲取客戶端的IP地址與C++和遇到的一個問題:如何節儉
有沒有辦法讓客戶端的IP地址從服務方法實現內部?我正在使用TNonblockingServer。
提前致謝!
Ticket THRIFT-1053描述了一個類似的Java請求。該解決方案基本上允許訪問內部(端點)傳輸並從中檢索數據。沒有經過真正的測試,爲C++構建類似的解決方案應該很容易。由於您使用的是Thrift 0.4.0,因此我強烈建議先查看當前中繼(0.9.3)。該TBufferedTransport
,TFramedTransport
和TShortReadTransport
已經實現了
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
在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);
#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);