下载 0.9.1 版本 (0.9.2需要 2.5的bison,而 RHEL6上自带bison是2.4)

 
TNonblockingServer 时必须使用 TFramedTransport ,不能使用 TBufferedTransport,因为前者会先写入这个消息的字节数。这样非阻塞时可以预知消息的大小。

 
 
 
1. 服务端获取请求方的IP
网上流传最多的是扩展 
bool TDispatchProcessor::process(boost::shared_ptr<protocol::TProtocol> in,
                       boost::shared_ptr<protocol::TProtocol> out,
                       void* connectionContext) 
从 in 获得 transport 然后获得 TSocket 对象。但这个方法只适合阻塞式的 TSimpleServer 和 TThreadPoolServer 等,并不适合 TNonblockingServer。使用 TNonblockingServer 时,可通过扩展 void TServerEventHandler::processContext(void* serverContext, boost::shared_ptr<TTransport> transport) ,这里 transport 参数是个 TSocket 对象,而这个函数总会在调用 processor 处理请求之前被调用。
 
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, 复用 TNonblockingServer::TConnection 导致 getPeerAddress() 返回脏数据, 见 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);
 TNonblockingServer 复用 TNonblockingServer::TConnection 对象,但调用 TSocket::setCachedAddress() 并没有清掉 peerAddress_ 和 peerHost_ ,导致脏数据。
需要 TSocket::setCachedAddress() 函数中清除 这2个变量
lib/cpp/src/thrift/transport/TSocket.cpp
void TSocket::setCachedAddress(const sockaddr* addr, socklen_t len) {
if (!path_.empty()) {
return;
} switch (addr->sa_family) {
case AF_INET:
if (len == sizeof(sockaddr_in)) {
memcpy((void*)&cachedPeerAddr_.ipv4, (void*)addr, len);
}
break; case AF_INET6:
if (len == sizeof(sockaddr_in6)) {
memcpy((void*)&cachedPeerAddr_.ipv6, (void*)addr, len);
}
break;
}
peerAddress_.clear(); // ++
peerHost_.clear(); // ++
}
 
 
2. 禁用监听 IPv6
阻塞式服务需要修改 lib/cpp/src/thrift/transport/TServerSocket.cpp 的 
TServerSocket::listen() 函数,修改 hints.ai_family = PF_INET;
而 TNonblockingServer 需要修改 lib/cpp/src/thrift/transport/TNonblockingServer.cpp
TNonblockingServer::createAndListenOnSocket() 函数,修改 hints.ai_family = PF_INET;
 
 
 
3. 切换 libevent 为 libev
由于项目中用到了 libev,而 thrift 的 TNonblockingServer 用到 libevent,而它们头文件有名字冲突。libev 做了个简单的 libevent 适配接口,但 thrift 还用到了 创建 socketpair 设置 socket close on exec 等函数,我简单的从 libevent 拷贝过来,即编译成功。 (sockepair 本来理论上可以用 libev 的 ev_async 替代的,但由于这里 thrift 直接把 TConnection 的指针通过 socket 传递,有个队列的功能在里面了,稍花时间就没做)
 
因为前面 TNonblockingServer 复用 TConnection 和 TSocket 导致TSocket::getPeerAddress() 脏数据,需要修改 TSocket 源码,为了更好的发布,我把 TNonblockingServer 单独提到项目中,并直接禁用了复用 TConnection ,这样使用默认 thrift 库即可。
 
修改后的 TNonblockingServer文件
 
 
 

thrift TNonblockingServer 使用的更多相关文章

  1. 服务化实战之 dubbo、dubbox、motan、thrift、grpc等RPC框架比较及选型

    转自: http://blog.csdn.net/liubenlong007/article/details/54692241 概述 前段时间项目要做服务化,所以我比较了现在流行的几大RPC框架的优缺 ...

  2. dubbo、dubbox、motan、thrift、grpc等RPC框架比较及选型

    概述 前段时间项目要做服务化,所以我比较了现在流行的几大RPC框架的优缺点以及使用场景,最终结合本身项目的实际情况选择了使用dubbox作为rpc基础服务框架.下面就简单介绍一下RPC框架技术选型的过 ...

  3. RPC调用框架比较分析

    什么是RPC: RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. 简言之,RPC ...

  4. Thrift 使用TNonblockingServer模型时调用PosixThreadFactory出错。

    Thrift 使用TNonblockingServer模型时调用PosixThreadFactory出错.   我定位到shared_ptr<PosixThreadFactory> thr ...

  5. 和 Thrift 的一场美丽邂逅

    一. 与 Thrift 的初识 也许大多数人接触 Thrift 是从序列化开始的.每次搜索 “java序列化” + “方式”.“对比” 或 “性能” 等关键字时,搜索引擎总是会返回一大堆有关各种序列化 ...

  6. dubbo/dubbox 增加原生thrift及avro支持

    (facebook) thrift / (hadoop) avro / (google) probuf(grpc)是近几年来比较抢眼的高效序列化/rpc框架,dubbo框架虽然有thrift的支持,但 ...

  7. Thrift-java学习小结

    ➠更多技术干货请戳:听云博客 Thrift是什么?什么情况下使用thrift Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开 ...

  8. Thrift入门及Java实例演示<转载备用>

    Thrift入门及Java实例演示 作者: Michael 日期: 年 月 日 •概述 •下载配置 •基本概念 .数据类型 .服务端编码基本步骤 .客户端编码基本步骤 .数据传输协议 •实例演示(ja ...

  9. Golang通过Thrift框架完美实现跨语言调用

    每种语言都有自己最擅长的领域,Golang 最适合的领域就是服务器端程序. 做为服务器端程序,需要考虑性能同时也要考虑与各种语言之间方便的通讯.采用http协议简单,但性能不高.采用TCP通讯,则需要 ...

随机推荐

  1. Qt之HTTP上传/下载(继承QNetworkAccessManager,包括使用了authenticationRequired认证信号)

    效果 QNetworkAccessManager DownloadNetworkManager::DownloadNetworkManager(QObject *parent) : QNetworkA ...

  2. C#中Split分隔字符串的应用(C#、split、分隔、字符串)

    转载地址 .用字符串分隔: using System.Text.RegularExpressions; string str="aaajsbbbjsccc"; string[] s ...

  3. 【LeetCode练习题】Combination Sum

    Combination Sum Given a set of candidate numbers (C) and a target number (T), find all unique combin ...

  4. PHP 9 大缓存技术总结

    1.全页面静态化缓存 也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程.此种方式,在CMS系统中比较常见,比如dedecms: 一种比较常用的实现方 ...

  5. IsDbNull 方法的用法

    本文来自:http://lazhgg.cnblogs.com/archive/2006/02/21/334915.html 在c#中,进行数据库查询时使用IsDbNull 方法判断数据库中字段值是否存 ...

  6. 【二分答案】 【POJ3497】 【Northwestern Europe 2007】 Assemble 组装电脑

    Assemble Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3171   Accepted: 1013 Descript ...

  7. 浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘。

    一.浏览器渲染页过程描述 1.浏览器解析html源码,然后创建一个DOM树. 在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点). DOM树 ...

  8. css系列教程--简介及基础语法和注意事项

    css简介:css指的是层叠样式表,cascading style sheets.用来定义html中的dom节点如何展示在页面中的问题.解决了内容与表现形式的分离问题.常见的样式表有外部链接样式表和内 ...

  9. hadoop python and Twitter

    http://www.wubiaoblog.com/archives/1159 http://blog.csdn.net/anbo724 http://f.dataguru.cn/forum.php? ...

  10. 安装Cocoapoads遇到的问题的解决办法

    错误一.首先来个错误截图