Advertisement
AlexNovoross87

quest

Jun 13th, 2025 (edited)
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.12 KB | None | 0 0
  1. Здравствуйте, вопрос заключается в следующем:
  2.  
  3. Перед нами классический буст-бистовский асинксервер, но есть нюанс:
  4. В классике все происходило Read->Onread->Write->OnWrite->Read
  5.  
  6. В функциях Read и Write был вызов асинхронных операций, и если повторно вызывать
  7. асинхронную операцию допустим read пока не было срабатывания предыдущей - бустовский ассерт падает.
  8.  
  9. Теперь к сути вопроса: (полная работа функции ниже тут только сама суть)
  10.  
  11. Ввожу понятие DIR то есть разделение откуда была вызвана Write. После OnRead или с внешнего источника.
  12. Вместо асинхронной версии делаю синхронную под защитой мютекса. То есть больше одного потока не начнет
  13. писать в сокет:
  14.  
  15. void AbstractSession::Write(DIR dir,std::string responce_body, http::status status)
  16. {
  17. std::lock_guard<std::mutex> lg(mtx_use_write_);
  18. err ec;
  19. auto bytes = http::write(*stream_, std::move(rsp), ec); // async write была
  20. OnWrite(dir, true, ec, bytes);
  21. };
  22.  
  23. И наконец если запрос на запись пришел сверху (с Read()), где было срабатывание асинк-рида то мы снова вызываем Read() и ждем запрос новый, А если пришел из другого класса, то после записи мы не вызываем Read() так как он уже ждет нового входящего запроса на обработку..
  24. void AbstractSession::OnWrite(DIR dir, bool keep_alive, beast::error_code ec, std::size_t bytes_transferred)
  25. {
  26. if(dir == AbstractSession::DIR::OUTER) {return;}
  27. Read();
  28. }
  29.  
  30. Так норм будет работать или что-то упускаю ?? Например если у нас
  31. http::async_read(*stream_, *readbuf_, request_,
  32. beast::bind_front_handler(&AbstractSession::OnRead, shared_from_this()));
  33. уже взведен, а в это время мы начинаем писать в сокет со стороны.. методом Write..
  34.  
  35. Буду очень признателен, заранее спасибо!
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45. //////////////////////////////// Реализация класса
  46. VVVVVVVV
  47. void AbstractSession::Read()
  48. {
  49. request_ = {};
  50. if (!stream_)
  51. {
  52. ZyncPrint("STREAM SESSION IS DAMAGED........READ()");
  53. return;
  54. }
  55. // ПРОВЕРЯЕМ ЖИВ ЛИ СОКЕТ
  56. if (!Service::IsAliveSocket(stream_->socket()))
  57. {
  58. ZyncPrint("SOCKET IS DAMAGED...........READ()");
  59. Service::ShutDownSocket(stream_->socket());
  60. return;
  61. }
  62.  
  63. // Начинаем асинхронноен чтение
  64. // std::lock_guard<std::mutex> lg(mtx_use_buf_);
  65. http::async_read(*stream_, *readbuf_, request_,
  66. beast::bind_front_handler(&AbstractSession::OnRead, shared_from_this())); // async read until
  67. };
  68.  
  69. void AbstractSession::OnRead(err ec, size_t bytes)
  70. {
  71. if (!ec)
  72. { // Обрабатываем прочитанные данные
  73. StartAfterReadHandle();
  74. }
  75. else
  76. {
  77. ZyncPrint("ON READ----> " + ec.message());
  78. }
  79. };
  80.  
  81. void AbstractSession::Run()
  82. {
  83. if(!stream_) {
  84. ZyncPrint("THE STREAM IS DAMAGED...........RUN()");
  85. return;
  86. }
  87.  
  88. net::dispatch(stream_->get_executor(),
  89. beast::bind_front_handler(
  90. &AbstractSession::Read,
  91. shared_from_this()));
  92. };
  93.  
  94. void AbstractSession::Write(DIR dir,std::string responce_body, http::status status)
  95. {
  96. try
  97. {
  98. std::lock_guard<std::mutex> lg(mtx_use_write_);
  99. response rsp(Service::MakeResponce(
  100. 11, true,
  101. http::status::ok, std::move(responce_body)));
  102.  
  103.  
  104.  
  105. // ПИШЕМ В СОКЕТ
  106. err ec;
  107. auto bytes = http::write(*stream_, std::move(rsp), ec); // async writ
  108. OnWrite(dir, true, ec, bytes);
  109.  
  110. }
  111. catch (const std::exception &ex)
  112. {
  113. ZyncPrint("WriteToSocketEXCERPTION", ex.what());
  114. }
  115. };
  116.  
  117. void AbstractSession::OnWrite(DIR dir, bool keep_alive, beast::error_code ec, std::size_t bytes_transferred)
  118. {
  119.  
  120. boost::ignore_unused(bytes_transferred);
  121. if (ec)
  122.  
  123. if (!keep_alive)
  124. {
  125. ZyncPrint("No Keep Alive, Closing.............");
  126. Close();
  127. return;
  128. }
  129. // Read another request
  130. ZyncPrint("WriteComplete.............");
  131. // request_ = {};
  132. if(dir == AbstractSession::DIR::OUTER) {return;}
  133. Read();
  134. }
  135.  
  136. void AbstractSession::Close()
  137. {
  138. beast::error_code ec;
  139. stream_->socket().shutdown(tcp::socket::shutdown_send, ec);
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement