Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Здравствуйте, вопрос заключается в следующем:
- Перед нами классический буст-бистовский асинксервер, но есть нюанс:
- В классике все происходило Read->Onread->Write->OnWrite->Read
- В функциях Read и Write был вызов асинхронных операций, и если повторно вызывать
- асинхронную операцию допустим read пока не было срабатывания предыдущей - бустовский ассерт падает.
- Теперь к сути вопроса: (полная работа функции ниже тут только сама суть)
- Ввожу понятие DIR то есть разделение откуда была вызвана Write. После OnRead или с внешнего источника.
- Вместо асинхронной версии делаю синхронную под защитой мютекса. То есть больше одного потока не начнет
- писать в сокет:
- void AbstractSession::Write(DIR dir,std::string responce_body, http::status status)
- {
- std::lock_guard<std::mutex> lg(mtx_use_write_);
- err ec;
- auto bytes = http::write(*stream_, std::move(rsp), ec); // async write была
- OnWrite(dir, true, ec, bytes);
- };
- И наконец если запрос на запись пришел сверху (с Read()), где было срабатывание асинк-рида то мы снова вызываем Read() и ждем запрос новый, А если пришел из другого класса, то после записи мы не вызываем Read() так как он уже ждет нового входящего запроса на обработку..
- void AbstractSession::OnWrite(DIR dir, bool keep_alive, beast::error_code ec, std::size_t bytes_transferred)
- {
- if(dir == AbstractSession::DIR::OUTER) {return;}
- Read();
- }
- Так норм будет работать или что-то упускаю ?? Например если у нас
- http::async_read(*stream_, *readbuf_, request_,
- beast::bind_front_handler(&AbstractSession::OnRead, shared_from_this()));
- уже взведен, а в это время мы начинаем писать в сокет со стороны.. методом Write..
- Буду очень признателен, заранее спасибо!
- //////////////////////////////// Реализация класса
- VVVVVVVV
- void AbstractSession::Read()
- {
- request_ = {};
- if (!stream_)
- {
- ZyncPrint("STREAM SESSION IS DAMAGED........READ()");
- return;
- }
- // ПРОВЕРЯЕМ ЖИВ ЛИ СОКЕТ
- if (!Service::IsAliveSocket(stream_->socket()))
- {
- ZyncPrint("SOCKET IS DAMAGED...........READ()");
- Service::ShutDownSocket(stream_->socket());
- return;
- }
- // Начинаем асинхронноен чтение
- // std::lock_guard<std::mutex> lg(mtx_use_buf_);
- http::async_read(*stream_, *readbuf_, request_,
- beast::bind_front_handler(&AbstractSession::OnRead, shared_from_this())); // async read until
- };
- void AbstractSession::OnRead(err ec, size_t bytes)
- {
- if (!ec)
- { // Обрабатываем прочитанные данные
- StartAfterReadHandle();
- }
- else
- {
- ZyncPrint("ON READ----> " + ec.message());
- }
- };
- void AbstractSession::Run()
- {
- if(!stream_) {
- ZyncPrint("THE STREAM IS DAMAGED...........RUN()");
- return;
- }
- net::dispatch(stream_->get_executor(),
- beast::bind_front_handler(
- &AbstractSession::Read,
- shared_from_this()));
- };
- void AbstractSession::Write(DIR dir,std::string responce_body, http::status status)
- {
- try
- {
- std::lock_guard<std::mutex> lg(mtx_use_write_);
- response rsp(Service::MakeResponce(
- 11, true,
- http::status::ok, std::move(responce_body)));
- // ПИШЕМ В СОКЕТ
- err ec;
- auto bytes = http::write(*stream_, std::move(rsp), ec); // async writ
- OnWrite(dir, true, ec, bytes);
- }
- catch (const std::exception &ex)
- {
- ZyncPrint("WriteToSocketEXCERPTION", ex.what());
- }
- };
- void AbstractSession::OnWrite(DIR dir, bool keep_alive, beast::error_code ec, std::size_t bytes_transferred)
- {
- boost::ignore_unused(bytes_transferred);
- if (ec)
- if (!keep_alive)
- {
- ZyncPrint("No Keep Alive, Closing.............");
- Close();
- return;
- }
- // Read another request
- ZyncPrint("WriteComplete.............");
- // request_ = {};
- if(dir == AbstractSession::DIR::OUTER) {return;}
- Read();
- }
- void AbstractSession::Close()
- {
- beast::error_code ec;
- stream_->socket().shutdown(tcp::socket::shutdown_send, ec);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement