最近在项目中需要把客户端的一些信息发送到服务器上,听起来是个很简单的需求,但是实际考虑下,觉得如果自己手工实现,工作量也不小,而且尽是些繁琐且无聊的事情,遂考虑用现成的库来实现。对比了protocol buffer与thrift后,本着偷懒到底的原则,选择了thrift,因为thrift本身提供了RPC框架,而protocol buffer仅是个序列化的库而已。

首先是编译thrift,这里参考官方说明,需要先装boost库,但是如果要使用nonblocking server的话,还要再把libevent库也装上。

thrift提供了三种服务模型,分别是TSimpleServer, TThreadPoolServer和TNonblockingServer,除去第一个一般仅做测试用,后两个都可以在实际生产中拿来用。在客户端不多的情况下,可以选用TThreadPoolServer,但是要注意TThreadPoolServer的客户端只要不从服务器上断开连接,就会一直占据服务器的一个线程,当服务器线程池所有线程都在被使用时,新到来的客户端将排在队列里等待,直到有客户端断开连接,使服务器端线程池出现空闲线程方可继续被提供服务,所以使用这种模型时,一定要注意客户端不使用时不要长时间连接服务器,如果确实有这种需求,请使用TNonblockingServer。

说实话,单纯从代码量上来讲,使用Nonblocking server并不比ThreadPool server多了多少,谁让代码都是由thrift程序生成的,用户只需填上实际处理的代码即可。

下面用一个简单的例子说明

clientInfo.thrift

[plain] view plain copy
  1. namespace cpp vnmp
  2. enum ClientType {
  3. DOM_MANAGER,
  4. DOM_SERVICE
  5. }
  6. enum RegistResult {
  7. SUCCESS,
  8. NAME_EXISTED,
  9. INVALIE_PARA,
  10. }
  11. struct ClientInfo {
  12. 1: string name,
  13. 2: string realIP,
  14. 3: string vpnIP,
  15. 4: ClientType type,
  16. 5: optional string description,
  17. }
  18. service Regist {
  19. RegistResult registClient(1:ClientInfo clientInfo),
  20. bool heartbeat(1:string name, 2:ClientType type)
  21. }

对这个文件做一个简单的说明,client需要把自己的信息ClientInfo发送到server上注册,调用registClient方法,heartbeat方法是用来做心跳的。

执行 thrift -r --gen cpp clientInfo.thrift

如果没有语法错误的话,在gen-cpp目录下会生成

clientInfo_constants.h clientInfo_constants.cpp

clientInfo_types.h clientInfo_types.cpp

Regist_server.skeleton.cpp

其中的skeleton文件包含了一个简单的TSimpleServer实现,是可以直接编译使用的,这个文件也就是我们要修改的文件,建议另外建一个main文件,并将其中内容拷过来,其他几个强烈建议不要做修改,一来没需要,二来如果做了修改,下次执行thrift文件时,也会被新生成的文件覆盖,这也是我前面建议另外建一个main文件还不是直接修改skeketon文件的原因。

下面是main文件的主要内容,略去了头文件的包含和命名空间的使用等等,这里假定读者已有了一定的boost基础。

[cpp] view plain copy
  1. class RegistHandler : virtual public RegistIf {
  2. public:
  3. RegistHandler() {
  4. // Your initialization goes here
  5. }
  6. RegistResult::type registClient(const ClientInfo& clientInfo) {
  7. // Your implementation goes here
  8. printf("registClient\n");
  9. }
  10. void heartbeat(const std::string& name, const ClientType::type type) {
  11. // Your implementation goes here
  12. printf("heartbeat\n");
  13. }
  14. };
  15. int main(int argc, char **argv) {
  16. int port = 9090;
  17. shared_ptr<RegistHandler> handler(new RegistHandler());
  18. shared_ptr<TProcessor> processor(new RegistProcessor(handler));
  19. shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
  20. shared_ptr<ThreadManager> threadManager = ThreadManager::newSimpleThreadManager(15);
  21. shared_ptr<PosixThreadFactory> threadFactory = shared_ptr<PosixThreadFactory > (new PosixThreadFactory());
  22. threadManager->threadFactory(threadFactory);
  23. threadManager->start();
  24. TNonblockingServer server(processor, protocolFactory, port, threadManager);
  25. server.serve();
  26. return 0;
  27. }

regist service的实际处理方法写在registHandler对应的方法里。主要是main方法做个简单说明:

这里使用了thrift库自带的ThreadManager,建立了一个拥有15个线程的线程池,也就是说这个NonblockingServer拥有15个工作线程。

除了shared_ptr来自boost,其他均是thrift自带,命名空间是apache::thrift

client端

[cpp] view plain copy
  1. int main(int argc, char** argv) {
  2. boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
  3. boost::shared_ptr<TTransport> transport(new TFramedTransport(socket));
  4. boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
  5. RegistClient client(protocol);
  6. transport->open();
  7. //insert your code here
  8. //      ....
  9. transport->close();
  10. return 0;
  11. }

注意对于nonblocking server,client端的TTransport只能选用TFramedTransport;如果通信过程中出现异常,会抛出异常,可以用try catch捕获并做处理。

thrift中TNonblockingServer的简单用法相关推荐

  1. python count函数代码_python中count函数简单用法

    python中count函数简单用法 python中count函数的用法 Python count()方法 描述 Python count() 方法用于统计字符串里某个字符出现的次数.可选参数为在字符 ...

  2. android中checkbox使用方法,Android开发中CheckBox的简单用法示例

    本文实例讲述了Android开发中CheckBox的简单用法.分享给大家供大家参考,具体如下: CheckBox是一种在界面开发中比较常见的控件,Android中UI开发也有CheckBox,简单的说 ...

  3. C#窗体设计中ToolTip的简单用法

    本文介绍C#窗体设计中ToolTip的简单用法. 操作流程 1.1. ToolTip信息提示框作用 C#中提供了信息提示框,这有很多用处,可以提示控件或者用户自定义的属性信息,而且可以自动弹出或者用户 ...

  4. C++中的Lock简单用法

    简单记录一下C++中的Lock的用法 下面是使用临界区进行线程同步 首先定义一个临界区对象 CCriticalSection m_CritSect; //临界对象,同步线程使用 在需要使用到可能起冲突 ...

  5. Shellz中awk的简单用法

    其实shell脚本的功能常常被低估.在实际应用中awk sed 等用法可以为shell提供更为强大的功能.下面我们将一下awk调用的简单方法进行了总结.方便同学们学习: awk的简单用法: 第一种调用 ...

  6. **matlab中fprintf函数简单用法**

    1.fprintf函数:将数据按指定格式写入到文本文件中. 2.用法说明: fprintf(fid, format, variables): 按指定的格式将变量的值输出到屏幕或指定文件: fid为文件 ...

  7. python 中 feedparser的简单用法

    最近在机器学习实战中用到feedparser ,然后简单总结了一下: feedparser是python中最常用的RSS程序库,使用它我们可轻松地实现从任何 RSS 或 Atom 订阅源得到标题.链接 ...

  8. C# Winfom 中ListBox的简单用法

    Winform控件ListBox的用法 1.如何添加listBox的值 this.listBox1.Items.Add("张晓东"); 2.如何判断listBox集合是否添加过 / ...

  9. python中parse.add_argument()简单用法

    argparse模块简单使用流程以及与命令行的交互 1.导入模块 2.创建解析器 3.添加参数 4.解析参数 5使用参数 完整代码 与命令行的交互 argparse 模块是 Python 内置的一个用 ...

最新文章

  1. 用友u8 php,php 访问用友u8数据
  2. iOS,macOS,darwin,unix 简介
  3. 3.4 多个例子中的向量化-深度学习-Stanford吴恩达教授
  4. linux增加 路由使两个不同的网段可以访问
  5. jmeter 线程执行顺序_性能测试之jmeter逻辑控制种类详解一
  6. JBox2d入门学习二 -----我的小鸟
  7. 遥感图像预处理-大气校正
  8. SNMP原理和MIB库
  9. ldo和dcdc功耗_LDO和DCDC电源的优缺点以及差别
  10. Win10删除文件需要管理员权限则怎么办?
  11. 8位12指令微程序CPU设计
  12. debian怎么安装oracle数据库,Debian上安装Oracle客户端
  13. Mac上使用Docker Desktop启动Kubernetes,踩坑后终于搞掂
  14. 支付宝生活号开发中所遇到的困难及解决记录
  15. centos7 完美适配QQ,TIM,微信,Foxmail,迅雷,有道云笔记,钉钉,金山词霸,爱奇艺,百度云盘,QQ音乐
  16. C语言中%*s,%*c (还有%*.*s)
  17. 文本数据的词云可视化
  18. ansys添加力矩_ANSYS如何施加转矩(周向载荷) -
  19. 微雪新款HDMI液晶框架安装
  20. 一文掌握SPFA算法

热门文章

  1. pom.xml文件第一行报错_Python文件读写指南
  2. 解决“Class org.apache.hadoop.hdfs.DistributedFileSystem not found“问题
  3. “过午不食”实锤了!协和医院最新研究:每天6:00-15:00进食,其它时间不吃饭!...
  4. 三大高通量测序平台芯片通量对比图(请把手机横过来看))
  5. 生物科研神器!30分钟把人家一天的工作都给干完了!
  6. 文章用图的修改和排版(2)
  7. iCloud怎么协同作业文? iCloud怎么协同编辑文档?
  8. ps专业色彩调色扩展面板 Moody Photoshop Panel 1.1.2汉化版
  9. adb push命令传文件到手机_Android调试桥(adb)
  10. 【chorme插件开发】第二节:插件的配置文件说明及素材