下载 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. CentOS安装错误:no default or ui configuration

    靠,以后再也不用浏览器自带的下载工具下载镜像文件了,原来是下载的不完整,但是显示完全下载完毕了,真特么误导人.文件的checksum不对. references: https://www.centos ...

  2. 学DSP(二):目标芯片28335,GO!

    28335开发板有了,之前没有用过TI的片子,还是先看看这个东西是啥东西. 进入28335的中文网页: http://www.ti.com.cn/product/cn/tms320f28335    ...

  3. Kth Smallest Element in a BST 解答

    Question Given a binary search tree, write a function kthSmallest to find the kth smallest element i ...

  4. HDU4762(JAVA大数)

    Cut the Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  5. 怎样使用LaTeX输入葡萄牙语等语言中的特殊字符

    论文中引用了大名鼎鼎ER random graph model,但是这两位的名字不太好打,发现Google Scholar中直接下载的bib文件中也是错的.找了一会,发现转义字符已经定义得很好了.只是 ...

  6. oracle 查询表名以及表的列名

    oracle 查询表名以及表的列名的代码.   1.查询表名: 代码如下: select table_name,tablespace_name,temporary from user_tables [ ...

  7. Ajax下载文件(页面无刷新)

    说明:Ajax是无法实现文件传输的,本文只是模拟了Ajax不刷新页面就可以请求并返回数据的效果.实质上还是通过提交form表单来返回文件流的输出. 分步实现逻辑: ajax请求服务器,访问数据库,根据 ...

  8. 所闻所获6:meditashayne项目总结

    项目源码下载地址: https://github.com/ShayneYeorg/Meditashayne 1.首先一开始设计这个App的时候,我就希望它能比系统自带的备忘录更方便:比如备忘录需要手动 ...

  9. 【二分查找+优化O(n)】【续UVA1121】Subsequence

    之前的二分答案做法 http://blog.csdn.net/zy691357966/article/details/40212215 二分查找做法: 我们首先试试只枚举终点.对于终点j,我们的目标是 ...

  10. java学习之i/o

    基本的输入输出  这里有两种方法,其中一种被注释了,可以换着注释后测试一遍 class TestSystem { public static void main(String[] args) { /* ...