HTTP协议支持示例

概述

TARS服务框架默认情况下只支持TARS自有的tars协议,但是在实际的应用场景中,需要在TARS服务框架中支持其他协议,例如HTTP,这种情况下就不能用通信器来发送据,需要业务自己来实现这部分代码。对于自定义的协议, 处理方式也类似

具体程序示例,参见examples/httpDemo/.

开发第三方协议服务端,要实现协议解析器并将其加载到服务中,同时需要建立一个非TAF框架的服务对象,该类继承于Servant类,通过重载Servant类中的doRequest方法来建立协议处理器。 而客户端要访问服务,需要通过调用proxy的rpc函数,在调用之前,要为proxy设置请求包编码函数和响应包解码函数。

HTTP协议支持示例 - 图1

图中的黑色线代表了数据流向:数据(客户端)-〉请求包的编码器(客户端)-〉协议解析器(服务端)-〉doRequest协议处理器(服务端)-〉生成返回数据(服务端)-〉响应包的解码器(客户端)-〉响应数据(客户端)

其中请求包的编码器(客户端)负责对客户端发送的数据进行打包,协议解析器(服务端)负责对收到的数据进行解析并交给协议处理器(服务端)去处理并生成返回数据,而响应包的解码器(客户端)负责对返回的数据进行解码。

服务端Http协议实例

/usr/local/tars/cpp/script/create_tars_server.sh TestApp HttpServer Http

在目录下会生成六个文件,将http.tars 删除(因为不是tars协议),然后手动的实现一些方法

以HelloServer为例,需要支持http协议

在HttpImp中修改继承自Servant类的doRequest方法,该方法为第三方服务的处理器,该处理器负责处理协议解析器传送给其的数据,并负责生成返回给客户端的response

HttpImp.h

  1. #ifndef _HttpImp_H_
  2. #define _HttpImp_H_
  3. #include "servant/Application.h"
  4. /**
  5. *
  6. *
  7. */
  8. class HttpImp : public Servant
  9. {
  10. public:
  11. /**
  12. *
  13. */
  14. virtual ~HttpImp() {}
  15. /**
  16. *
  17. */
  18. virtual void initialize();
  19. /**
  20. *
  21. */
  22. virtual void destroy();
  23. /**
  24. *
  25. */
  26. int doRequest(TarsCurrentPtr current, vector<char> &buffer);
  27. };
  28. /////////////////////////////////////////////////////
  29. #endif

HttpImp.cpp

  1. #include "HttpImp.h"
  2. #include "servant/Application.h"
  3. using namespace std;
  4. //////////////////////////////////////////////////////
  5. void HttpImp::initialize()
  6. {
  7. //initialize servant here:
  8. //...
  9. }
  10. //////////////////////////////////////////////////////
  11. void HttpImp::destroy()
  12. {
  13. //destroy servant here:
  14. //...
  15. }
  16. int HttpImp::doRequest(TarsCurrentPtr current, vector<char> &buffer)
  17. {
  18. TC_HttpRequest request;
  19. vector<char> v = current->getRequestBuffer();
  20. string sBuf;
  21. sBuf.assign(&v[0],v.size());
  22. request.decode(sBuf);
  23. TC_HttpResponse rsp;
  24. string s="hello";
  25. rsp.setResponse(s.c_str(),s.size());
  26. rsp.encode(buffer);
  27. return 0;
  28. }

在其中HttpServer类的initialize(),加载服务对象HttpImp,并设置第三方协议解析器parse。 我们在函数中实现HttpProtocol::parse函数,用于解析协议。

  1. #ifndef _HttpServer_H_
  2. #define _HttpServer_H_
  3. #include <iostream>
  4. #include "servant/Application.h"
  5. using namespace tars;
  6. /**
  7. *
  8. **/
  9. class HttpServer : public Application
  10. {
  11. public:
  12. /**
  13. *
  14. **/
  15. virtual ~HttpServer() {};
  16. /**
  17. *
  18. **/
  19. virtual void initialize();
  20. /**
  21. *
  22. **/
  23. virtual void destroyApp();
  24. };
  25. extern HttpServer g_app;
  26. ////////////////////////////////////////////
  27. #endif
  1. #include "HttpServer.h"
  2. #include "HttpImp.h"
  3. using namespace std;
  4. HttpServer g_app;
  5. /////////////////////////////////////////////////////////////////
  6. struct HttpProtocol
  7. {
  8. /**
  9. * 解析http请求
  10. * @param in
  11. * @param out
  12. *
  13. * @return int
  14. */
  15. static int parseHttp(string &in, string &out)
  16. {
  17. try
  18. {
  19. //判断请求是否是HTTP请求
  20. bool b = TC_HttpRequest ::checkRequest(in.c_str(), in.length());
  21. //完整的HTTP请求
  22. if(b)
  23. {
  24. out = in;
  25. in = "";
  26. //TLOGDEBUG("out size: " << out.size() << endl);
  27. return TC_EpollServer::PACKET_FULL;
  28. }
  29. else
  30. {
  31. return TC_EpollServer::PACKET_LESS;
  32. }
  33. }
  34. catch(exception &ex)
  35. {
  36. return TC_EpollServer::PACKET_ERR;
  37. }
  38. return TC_EpollServer::PACKET_LESS; //表示收到的包不完全
  39. }
  40. };
  41. void
  42. HttpServer::initialize()
  43. {
  44. //initialize application here:
  45. //...
  46. addServant<HttpImp>(ServerConfig::Application + "." + ServerConfig::ServerName + ".HttpObj");
  47. addServantProtocol(ServerConfig::Application + "." + ServerConfig::ServerName + ".HttpObj",&HttpProtocol::parseHttp);
  48. }
  49. /////////////////////////////////////////////////////////////////
  50. void
  51. HttpServer::destroyApp()
  52. {
  53. //destroy application here:
  54. //...
  55. }
  56. /////////////////////////////////////////////////////////////////
  57. int
  58. main(int argc, char* argv[])
  59. {
  60. try
  61. {
  62. g_app.main(argc, argv);
  63. g_app.waitForShutdown();
  64. }
  65. catch (std::exception& e)
  66. {
  67. cerr << "std::exception:" << e.what() << std::endl;
  68. }
  69. catch (...)
  70. {
  71. cerr << "unknown exception." << std::endl;
  72. }
  73. return -1;
  74. }
  75. /////////////////////////////////////////////////////////////////