thrift通过TServerEventHandler获取客户端ip

用了这么久的thrift,一直不知道如何在接收端打印发送端的ip。一个笨的方法是在struct中添加字段并填充发送端的ip(或host),约定必须填充有效的ip,但这样不但增加了调用者的代码量,而且接收端还需要判断一个string字段是否为有效ip。

前段时间在网上查了一些资料,但无果。今天重新整理了这些资料,终于搞定了。

大致思路:http://web.archiveorange.com/archive/v/FzEy581cbgUiBLQh1GPv上讲的很清楚。我这里根据我的想法重复一下:

主要实现一个基类为TServerEventHandler的class,我叫它为ClientIPHandler。

1,定义一个map<uint64, string>,存放<pthread_self(), ip>。

2,在ClientIPHandler中createContext()里实现map的插入。

3,定义一个全局函数,获取map的值。这个函数供你的XServiceHandler(thrift自动生成的)使用。

4,在调用serve()前,定义shared_ptr<ClientIPHandler>变量a,调用setServerEventHandler设置eventHandler_(server/TServer.h:217).

map的读写需要加锁。

部分代码

static map<uint64, std::string> thrift_client_ip;
static base::lock::Mutex mutex;

std::string GetThriftClientIp() {
  lock::MutexLock g(&mutex);
  return thrift_client_ip[pthread_self()];
}
。。。

class ClientIPHandler : virtual public TServerEventHandler {
 public:
  ClientIPHandler() {
  }
  virtual ~ClientIPHandler() {
  }
  virtual void preServe() {
  }
  virtual void* createContext(boost::shared_ptr<TProtocol> input,
                              boost::shared_ptr<TProtocol> output) {
    TBufferedTransport *tbuf = dynamic_cast<TBufferedTransport *>(input->getTransport().get());
    TSocket *sock = dynamic_cast<TSocket *>(tbuf->getUnderlyingTransport().get());
    lock::MutexLock g(&mutex);
    thrift_client_ip[pthread_self()] = sock->getPeerAddress();
    return NULL;
  }
  virtual void deleteContext(void* serverContext,
                             boost::shared_ptr<TProtocol>input,
                             boost::shared_ptr<TProtocol>output) {
  }
  virtual void processContext(void* serverContext,
                              boost::shared_ptr<TTransport> transport) {
  }

 private:
};

。。。

  TThreadedServer server(processor,
                         serverTransport,
                         transportFactory,
                         protocolFactory);

  try {
    boost::shared_ptr<ClientIPHandler> ip_handler(new ClientIPHandler());
    server.setServerEventHandler(ip_handler);

    LOG(INFO)<< "thrift server start, listen port:" << listen_port;
    server.serve();
  } catch (apache::thrift::transport::TTransportException &ex) {
    LOG(FATAL) << ex.what();
  }

TServerEventHandler和TBufferedTransport需要相应的命名空间。

至此,我们可以在XServiceHandler中调用GetThriftClientIp()来获得客户端的ip了,终于不再烦恼数据是从哪里发来的了。

时间: 2024-10-31 07:27:20

thrift通过TServerEventHandler获取客户端ip的相关文章

php获取客户端IP

从Onethink代码里摘出来的 /**  * 获取客户端IP地址  * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字  * @return mixed  */ function get_client_ip($type = 0) {     $type       =  $type ? 1 : 0;     static $ip  =   NULL;     if ($ip !== NULL) return $ip[$type];     if 

php 获取客户端ip

1 function getRealIp() { 2 if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) 3 $ip = getenv("HTTP_CLIENT_IP"); 4 else if (getenv("HTTP_X_FORWARDED_FOR") && st

再论 ASP.NET 中获取客户端IP地址

说到IP获取无非是我们常见的以下几种方式,但是具体获取的值具体区别在哪?网上不乏相关文章,说的也是很详细,但是真正使用起来,还有很多不太对的地方.IP在不同系统中,应用相当广泛,常见的日志记录.广告分区域投放等. 1: HttpContext.Current.Request.ServerVariables["HTTP_VIA"]; 2: HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"

性能优化之——.NET(C#)调用webService获取客户端IP地址所属区域(异步回调)(二)

朋友们这次分享的是异步回调不是异步调用哦! 请注意喽! 功能描述,接口地址,方法名称以及参数说明,同上篇:.NET(C#)调用webService获取客户端IP地址所属区域(非异步)(一)(LZ比较懒,不想写太多哦!(⊙0⊙)) 实现代码如下: 1 namespace main 2 { 3 class Program 4 { 5 public static string Result = string.Empty; 6 7 static void Main(string[] args) 8 {

Netty4.X 获取客户端IP

最近使用netty-4.0.23.Final 版本编写服务端代码,有个获取客户端代码的小需求,以前使用servlet开发时很机械的就: String ipAddr="0.0.0.0"; if (reqest.getHeader("X-Forwarded-For") == null) {     ipAddr = reqest.getRemoteAddr();  }else{          ipAddr = req.getHeader("X-Forwar

.net 获取客户端Ip地址

Request.ServerVariables["REMOTE_ADDR"]来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代理服务器的IP地址,而不是真正的客户端IP地址. 要想透过代理服务器取得客户端的真实IP地址,就要使用 Request.ServerVariables["HTTP_X_FORWARDED_FOR"]来读取. 不过要注意的事,并不是每个代理服务器都能用 Request.ServerVariables["HTTP

strut2拦截器之获取客户端IP

下面是获取客户端iP的代码: 首先自定义一个拦截器 1 @Override 2 public String intercept(ActionInvocation ai) throws Exception { 3 ActionContext invocationContext = ai.getInvocationContext(); 4 HttpServletRequest httpservletrequest= (HttpServletRequest) invocationContext.get

C#服务器获取客户端IP地址以及归属地探秘

背景:博主本是一位Windows桌面应用程序开发工程师,对网络通信一知半解.一日老婆逛完某宝,问:"为什么他们知道我的地址呢,他们是怎么获取我的地址的呢?" 顺着这个问题我们的探秘开始: 第一步:简单的服务搭建 思路,通过HttpListener在本地搭建一个简易的服务器,开发程序为控制台接口,核心类 HttpListenerService: 方法 Start()开启线程池针对指定IP进行监听,本地的端口选取的9527(周星驰唐伯虎点秋香在华府的编号)  public void Sta

Mina获取客户端IP地址问题

使用Mina做Socket通信时,服务器端获取客户端IP地址,其实很简单,代码如下: @Override public void messageReceived(IoSession session, Object message) throws Exception { String clientIP = ((InetSocketAddress)session.getRemoteAddress()).getAddress().getHostAddress(); } 但是有时候却发现,session