/Example/Network/ProtoBuf/ProtoBufClient/ClientImpl.hpp

http://iocpframework.googlecode.com/ · C++ Header · 138 lines · 112 code · 26 blank · 0 comment · 8 complexity · 1aa05f92fac5f3096226ee47cc9fd984 MD5 · raw file

  1. #ifndef __CLIENT_IMPL_HPP
  2. #define __CLIENT_IMPL_HPP
  3. #include "test.pb.h"
  4. #include "../../../../include/Network/TCP.hpp"
  5. #include "../ProtoBuf/Dispatcher.hpp"
  6. #include "../ProtoBuf/Codec.hpp"
  7. using namespace async;
  8. using namespace std::tr1::placeholders;
  9. typedef std::tr1::shared_ptr<muduo::Empty> EmptyPtr;
  10. typedef std::tr1::shared_ptr<muduo::Answer> AnswerPtr;
  11. class Client
  12. {
  13. private:
  14. iocp::IODispatcher &io_;
  15. network::Tcp::Socket socket_;
  16. std::tr1::array<char, 4096> buf_;
  17. dispatch::ProtobufDispatcher<Client> dispatcher_;
  18. ProtobufCodec<Client> codec_;
  19. public:
  20. Client(iocp::IODispatcher &io, const std::string &ip, u_short port)
  21. : io_(io)
  22. , socket_(io, network::Tcp::V4())
  23. , dispatcher_(std::tr1::bind(&Client::_OnUnknownMessage, this, _1, _2))
  24. , codec_(std::tr1::bind(&dispatch::ProtobufDispatcher<Client>::OnProtobufMessage, &dispatcher_, _1, _2))
  25. {
  26. using namespace std::tr1::placeholders;
  27. dispatcher_.RegisterMessageCallback<muduo::Answer>(std::tr1::bind(&Client::_OnAnswer, this, _1, _2));
  28. dispatcher_.RegisterMessageCallback<muduo::Empty>(std::tr1::bind(&Client::_OnEmpty, this, _1, _2));
  29. try
  30. {
  31. socket_.AsyncConnect(network::IPAddress::Parse(ip), port,
  32. std::tr1::bind(&Client::_OnConnect, this, iocp::_Error, iocp::_Size));
  33. }
  34. catch(std::exception &e)
  35. {
  36. std::cerr << e.what() << std::endl;
  37. }
  38. }
  39. void Close()
  40. {
  41. socket_.Close();
  42. }
  43. template < typename MsgT >
  44. void Send(const MsgT &msg)
  45. {
  46. try
  47. {
  48. codec_.Send(socket_, msg,
  49. std::tr1::bind(&Client::_HandleWrite, this, iocp::_Error, iocp::_Size));
  50. }
  51. catch(std::exception &e)
  52. {
  53. std::cerr << e.what() << std::endl;
  54. }
  55. }
  56. private:
  57. void _OnConnect(u_long error, u_long bytes)
  58. {
  59. if( error != 0 )
  60. return;
  61. }
  62. void _HandleRead(u_long error, u_long bytes)
  63. {
  64. try
  65. {
  66. if( bytes == 0 )
  67. {
  68. socket_.AsyncDisconnect(std::tr1::bind(&Client::_DisConnect, this));
  69. return;
  70. }
  71. std::cout.write(buf_.data(), bytes) << std::endl;
  72. }
  73. catch(const std::exception &e)
  74. {
  75. std::cerr << e.what() << std::endl;
  76. }
  77. }
  78. void _HandleWrite(u_long error, u_long bytes)
  79. {
  80. try
  81. {
  82. if( error != 0 || bytes == 0 )
  83. {
  84. socket_.AsyncDisconnect(std::tr1::bind(&Client::_DisConnect, this));
  85. return;
  86. }
  87. iocp::AsyncRead(socket_, iocp::Buffer(buf_), iocp::TransferAtLeast(1),
  88. std::tr1::bind(&Client::_HandleRead, this, iocp::_Error, iocp::_Size));
  89. }
  90. catch(std::exception &e)
  91. {
  92. std::cerr << e.what() << std::endl;
  93. }
  94. }
  95. void _DisConnect()
  96. {
  97. socket_.Close();
  98. }
  99. void _OnUnknownMessage(Client &, const MessagePtr& message)
  100. {
  101. std::cout << "onUnknownMessage: " << message->GetTypeName();
  102. }
  103. void _OnAnswer(Client &, const AnswerPtr& message)
  104. {
  105. std::cout << "onAnswer:\n" << message->GetTypeName() << message->DebugString();
  106. }
  107. void _OnEmpty(Client &, const EmptyPtr& message)
  108. {
  109. std::cout << "onEmpty: " << message->GetTypeName();
  110. }
  111. };
  112. #endif