1
0

web-client.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include <functional>
  2. #include <thread>
  3. #include <memory>
  4. #include <memory>
  5. #include <ev++.h>
  6. #include "zio.h"
  7. #include "log.h"
  8. #include "zloop.h"
  9. #include "web-client.h"
  10. struct web_client_http:ev::io
  11. {
  12. char*m_buff;
  13. int m_pos,m_size;
  14. int m_fd,m_status;
  15. web_client_http()
  16. {
  17. m_fd=-1;
  18. m_pos=0;
  19. m_size=4096;
  20. m_buff=(char*)malloc(m_size);
  21. }
  22. int connect_tcp(const char*ip,int port)
  23. {
  24. int fd=zio::build_stream();
  25. if(zio::connect(fd,"127.0.0.1",4000))
  26. {
  27. zio::close(fd);
  28. return m_fd=-1;
  29. }
  30. zio::setiobuf(fd,16<<10,16<<10);
  31. zio::setblocking(fd,false);
  32. return m_fd=fd;
  33. }
  34. int connect_ws(const char*ip,int port)
  35. {
  36. const char*fmt=
  37. "GET / HTTP/1.1\n"
  38. "Connection:Upgrade\n"
  39. "Host:127.0.0.1:8088\n"
  40. "Sec-WebSocket-Extensions:x-webkit-deflate-frame\n"
  41. "Sec-WebSocket-Key:puVOuWb7rel6z2AVZBKnfw==\n"
  42. "Sec-WebSocket-Version:13\n"
  43. "Upgrade:webet\n";
  44. if(connect_tcp(ip,port)<0)
  45. return -1;
  46. int len=strlen(fmt);
  47. if(len!=zio::writev(m_fd,fmt,len))
  48. {
  49. close();
  50. return -1;
  51. }
  52. for(;;)
  53. {
  54. len=zio::read(m_fd,m_buff+m_pos,m_size-m_pos);
  55. if(len==-1)
  56. {
  57. close();
  58. return -1;
  59. }
  60. if(len==-2)
  61. continue;
  62. m_pos+=len;
  63. m_buff[m_pos]=0;
  64. if(strstr(m_buff,"\n\n"))
  65. break;
  66. }
  67. log_info("http debug:%s",m_buff);
  68. }
  69. void close()
  70. {
  71. zio::close(m_fd);
  72. }
  73. ~web_client_http()
  74. {
  75. close();
  76. ::free(m_buff);
  77. }
  78. };
  79. struct web_client_net_impl: web_client,zloop_base
  80. {
  81. std::unique_ptr<std::thread> m_thread;
  82. std::mutex m_mutex;
  83. std::list<std::string> m_req_list;
  84. ev::timer m_check_timer;
  85. std::string m_ip;
  86. int m_port;
  87. web_client_net_impl ()
  88. {
  89. m_thread.reset(new std::thread(std::bind(&web_client_net_impl::run,this)));
  90. }
  91. virtual void on_async_0()
  92. {
  93. if(check_stop_flag())
  94. return;
  95. std::list<std::string> async_list;
  96. {
  97. std::unique_lock<std::mutex> _lock(m_mutex);
  98. m_req_list.swap(async_list);
  99. }
  100. on_async(async_list);
  101. }
  102. void on_async(const std::list<std::string>&req)
  103. {
  104. }
  105. void on_check_timer(ev::timer&t,int)
  106. {
  107. }
  108. void run()
  109. {
  110. m_check_timer.set(*this);
  111. m_check_timer.set<web_client_net_impl,&web_client_net_impl::on_check_timer>(this);
  112. m_check_timer.start(0.,1.);
  113. ev::dynamic_loop::run(0);
  114. log_info("web_client_net_impl exit.");
  115. }
  116. void post(const char*m,int len)
  117. {
  118. {
  119. std::unique_lock<std::mutex> _lock(m_mutex);
  120. m_req_list.push_back(std::string(m,len));
  121. }
  122. m_async.send();
  123. }
  124. void stop()
  125. {
  126. async_stop();
  127. m_thread->join();
  128. }
  129. std::atomic<bool> m_start_flag{false};
  130. void start()
  131. {
  132. if(m_start_flag.load())
  133. return;
  134. m_start_flag.store(true);
  135. }
  136. };
  137. web_client*web_client::instance(const char*ip,int port,const char*path)
  138. {
  139. static web_client_net_impl impl;
  140. impl.start();
  141. return &impl;
  142. }