TarsCPP 快速入门

创建服务

运行tars脚本

  1. /usr/local/tars/cpp/script/create_tars_server.sh [App] [Server] [Servant]

本例中执行:/usr/local/tars/cpp/script/create_tars_server.sh TestApp HelloServer Hello

命令执行后,会在当前目录的TestApp/HelloServer/ 目录下,生成下面文件:

  1. HelloServer.h HelloServer.cpp Hello.tars HelloImp.h HelloImp.cpp makefile

这些文件,已经包含了最基本的服务框架和默认测试接口实现。

tars接口文件

定义tars接口文件的语法和使用,参见tars_tup.md。

如下:

Hello.tars:

  1. module TestApp
  2. {
  3. interface Hello
  4. {
  5. int test();
  6. };
  7. };

采用tars2cpp工具自动生成c++文件:/usr/local/tars/cpp/tools/tars2cpp hello.tars会生成hello.h文件,里面包含客户端和服务端的代码。

HelloImp是Servant的接口实现类

实现服务定义的tars件中的接口,如下:

HelloImp.h

  1. #ifndef _HelloImp_H_
  2. #define _HelloImp_H_
  3. #include "servant/Application.h"
  4. #include "Hello.h"
  5. /**
  6. * HelloImp继承hello.h中定义的Hello对象
  7. *
  8. */
  9. class HelloImp : public TestApp::Hello
  10. {
  11. public:
  12. /**
  13. *
  14. */
  15. virtual ~HelloImp() {}
  16. /**
  17. * 初始化,Hello的虚拟函数,HelloImp初始化时调用
  18. */
  19. virtual void initialize();
  20. /**
  21. * 析构,Hello的虚拟函数,服务析构HelloImp退出时调用
  22. */
  23. virtual void destroy();
  24. /**
  25. * 实现tars文件中定义的test接口
  26. */
  27. virtual int test(tars::TarsCurrentPtr current) { return 0;};
  28. };
  29. /////////////////////////////////////////////////////
  30. #endif

HelloImp.cpp:

  1. #include "HelloImp.h"
  2. #include "servant/Application.h"
  3. using namespace std;
  4. //////////////////////////////////////////////////////
  5. void HelloImp::initialize()
  6. {
  7. //initialize servant here:
  8. //...
  9. }
  10. //////////////////////////////////////////////////////
  11. void HelloImp::destroy()
  12. {
  13. //destroy servant here:
  14. //...
  15. }

HelloServer是服务的实现类

如下:

HelloServer.h:

  1. #ifndef _HelloServer_H_
  2. #define _HelloServer_H_
  3. #include <iostream>
  4. #include "servant/Application.h"
  5. using namespace tars;
  6. /**
  7. * HelloServer继承框架的Application类
  8. **/
  9. class HelloServer : public Application
  10. {
  11. public:
  12. /**
  13. *
  14. **/
  15. virtual ~HelloServer() {};
  16. /**
  17. * 服务的初始化接口
  18. **/
  19. virtual void initialize();
  20. /**
  21. * 服务退出时的清理接口
  22. **/
  23. virtual void destroyApp();
  24. };
  25. extern HelloServer g_app;
  26. ////////////////////////////////////////////
  27. #endif

HelloServer.cpp

  1. #include "HelloServer.h"
  2. #include "HelloImp.h"
  3. using namespace std;
  4. HelloServer g_app;
  5. /////////////////////////////////////////////////////////////////
  6. void
  7. HelloServer::initialize()
  8. {
  9. //initialize application here:
  10. //添加Servant接口实现类HelloImp与路由Obj绑定关系
  11. addServant<HelloImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".HelloObj");
  12. }
  13. /////////////////////////////////////////////////////////////////
  14. void
  15. HelloServer::destroyApp()
  16. {
  17. //destroy application here:
  18. //...
  19. }
  20. /////////////////////////////////////////////////////////////////
  21. int
  22. main(int argc, char* argv[])
  23. {
  24. try
  25. {
  26. g_app.main(argc, argv);
  27. g_app.waitForShutdown();
  28. }
  29. catch (std::exception& e)
  30. {
  31. cerr << "std::exception:" << e.what() << std::endl;
  32. }
  33. catch (...)
  34. {
  35. cerr << "unknown exception." << std::endl;
  36. }
  37. return -1;
  38. }
  39. /////////////////////////////////////////////////////////////////

服务编译

进入代码目录,首先做

  1. make cleanall
  2. make
  3. make tar

扩展功能

Tars框架提供了接口定义语言的功能,可以在tars文件中,增加一下接口和方法,扩展服务的功能。

可以修改由create_tars_server.sh生成的tars文件,以下3个接口方法中,test是默认生成的,testHello是新增加的接口。

  1. module TestApp
  2. {
  3. interface Hello
  4. {
  5. int test();
  6. int testHello(string sReq, out string sRsp);
  7. };
  8. };

使用/usr/local/tars/cpp/tools/tars2cpp hello.tars,重新生成hello.h。

修改HelloImp.h/HelloImp.cpp,实现新的接口代码。

其中HelloImp.h中继承Hello类的testHello方法:

  1. virtual int testHello(const std::string &sReq, std::string &sRsp, tars::TarsCurrentPtr current);

HelloImp.cpp实现testHello方法:

  1. int HelloImp::testHello(const std::string &sReq, std::string &sRsp, tars::TarsCurrentPtr current)
  2. {
  3. TLOGDEBUG("HelloImp::testHellosReq:"<<sReq<<endl);
  4. sRsp = sReq;
  5. return 0;
  6. }

重新make cleanall;make;make tar,会重新生成HelloServer.tgz发布包。

客户端同步/异步调用服务

在开发环境上,创建/home/tarsproto/[APP]/[Server]目录。

例如:/home/tarsproto/TestApp/HelloServer在刚才编写服务器的代码目录下,

执行 make release 这时会在/home/tarsproto/TestApp/HelloServer目录下生成h、tars和mk文件。

这样在有某个服务需要访问HelloServer时,就直接引用HelloServer服务make release的内容,不需要把HelloServer的tars拷贝过来(即代码目录下不需要存放HelloServer的tars文件)。

建立客户端代码目录,如TestHelloClient/。

编写main.cpp,创建实例并调用刚编写的接口函数进行测试。

同步方式:

  1. #include <iostream>
  2. #include "servant/Communicator.h"
  3. #include "Hello.h"
  4. using namespace std;
  5. using namespace TestApp;
  6. using namespace tars;
  7. int main(int argc,char ** argv)
  8. {
  9. Communicator comm;
  10. try
  11. {
  12. HelloPrx prx;
  13. comm.stringToProxy("TestApp.HelloServer.HelloObj@tcp -h 10.120.129.226 -p 20001" , prx);
  14. try
  15. {
  16. string sReq("hello world");
  17. string sRsp("");
  18. int iRet = prx->testHello(sReq, sRsp);
  19. cout<<"iRet:"<<iRet<<" sReq:"<<sReq<<" sRsp:"<<sRsp<<endl;
  20. }
  21. catch(exception &ex)
  22. {
  23. cerr << "ex:" << ex.what() << endl;
  24. }
  25. catch(...)
  26. {
  27. cerr << "unknown exception." << endl;
  28. }
  29. }
  30. catch(exception& e)
  31. {
  32. cerr << "exception:" << e.what() << endl;
  33. }
  34. catch (...)
  35. {
  36. cerr << "unknown exception." << endl;
  37. }
  38. return 0;
  39. }

异步方式

  1. #include <iostream>
  2. #include "servant/Communicator.h"
  3. #include "Hello.h"
  4. using namespace std;
  5. using namespace TestApp;
  6. using namespace tars;
  7. class HelloCallBack : public HelloPrxCallback
  8. {
  9. public:
  10. HelloCallBack(){}
  11. virtual ~HelloCallBack(){}
  12. virtual void callback_testHello(tars::Int32 ret, const std::string& sRsp)
  13. {
  14. cout<<"callback_testHello ret:"<< ret << "|sRsp:" << sRsp <<endl;
  15. }
  16. virtual void callback_testHello_exception(tars::Int32 ret)
  17. {
  18. cout<<"callback_testHello_exception ret:"<< ret <<endl;
  19. }
  20. };
  21. int main(int argc,char ** argv)
  22. {
  23. Communicator comm;
  24. try
  25. {
  26. HelloPrx prx;
  27. comm.stringToProxy("TestApp.HelloServer.HelloObj@tcp -h 10.120.129.226 -p 20001" , prx);
  28. try
  29. {
  30. string sReq("hello world");
  31. HelloPrxCallbackPtr cb = new HelloCallBack();
  32. prx->async_testHello(cb, sReq);
  33. cout<<" sReq:"<<sReq<<endl;
  34. }
  35. catch(exception &ex)
  36. {
  37. cerr<<"ex:"<<ex.what() <<endl;
  38. }
  39. catch(...)
  40. {
  41. cerr<<"unknown exception."<<endl;
  42. }
  43. }
  44. catch(exception& e)
  45. {
  46. cerr<<"exception:"<<e.what() <<endl;
  47. }
  48. catch (...)
  49. {
  50. cerr<<"unknown exception."<<endl;
  51. }
  52. getchar();
  53. return 0;
  54. }

编写makefile,里面包含刚才通过make release生成的/home/tarsproto/APP/Server目录下的mk文件,如下:

  1. #-----------------------------------------------------------------------
  2. APP :=TestApp
  3. TARGET :=TestHelloClient
  4. CONFIG :=
  5. STRIP_FLAG := N
  6. INCLUDE +=
  7. LIB +=
  8. #-----------------------------------------------------------------------
  9. include /home/tarsproto/TestApp/HelloServer/HelloServer.mk
  10. include /usr/local/tars/cpp/makefile/makefile.tars
  11. #-----------------------------------------------------------------------

make出目标文件,上传到能访问服务器的环境中进行运行测试即