mirror of
https://github.com/badaix/snapcast.git
synced 2025-07-19 01:18:17 +02:00
fix crash during heavy websocket load
This commit is contained in:
parent
5d7bac11ba
commit
e9dbb6c3b6
5 changed files with 103 additions and 49 deletions
|
@ -98,8 +98,9 @@ std::string path_cat(boost::beast::string_view base, boost::beast::string_view p
|
|||
}
|
||||
} // namespace
|
||||
|
||||
ControlSessionHttp::ControlSessionHttp(ControlMessageReceiver* receiver, tcp::socket&& socket, const ServerSettings::HttpSettings& settings)
|
||||
: ControlSession(receiver), socket_(std::move(socket)), settings_(settings)
|
||||
ControlSessionHttp::ControlSessionHttp(ControlMessageReceiver* receiver, boost::asio::io_context& ioc, tcp::socket&& socket,
|
||||
const ServerSettings::HttpSettings& settings)
|
||||
: ControlSession(receiver), socket_(std::move(socket)), settings_(settings), strand_(ioc)
|
||||
{
|
||||
LOG(DEBUG) << "ControlSessionHttp\n";
|
||||
}
|
||||
|
@ -115,7 +116,8 @@ ControlSessionHttp::~ControlSessionHttp()
|
|||
void ControlSessionHttp::start()
|
||||
{
|
||||
auto self = shared_from_this();
|
||||
http::async_read(socket_, buffer_, req_, [this, self](boost::system::error_code ec, std::size_t bytes) { on_read(ec, bytes); });
|
||||
http::async_read(socket_, buffer_, req_,
|
||||
boost::asio::bind_executor(strand_, [this, self](boost::system::error_code ec, std::size_t bytes) { on_read(ec, bytes); }));
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,7 +272,9 @@ void ControlSessionHttp::on_read(beast::error_code ec, std::size_t bytes_transfe
|
|||
|
||||
// Write the response
|
||||
auto self = this->shared_from_this();
|
||||
http::async_write(this->socket_, *sp, [this, self, sp](beast::error_code ec, std::size_t bytes) { this->on_write(ec, bytes, sp->need_eof()); });
|
||||
http::async_write(this->socket_, *sp, boost::asio::bind_executor(strand_, [this, self, sp](beast::error_code ec, std::size_t bytes) {
|
||||
this->on_write(ec, bytes, sp->need_eof());
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -297,7 +301,8 @@ void ControlSessionHttp::on_write(beast::error_code ec, std::size_t, bool close)
|
|||
req_ = {};
|
||||
|
||||
// Read another request
|
||||
http::async_read(socket_, buffer_, req_, [ this, self = shared_from_this() ](beast::error_code ec, std::size_t bytes) { on_read(ec, bytes); });
|
||||
http::async_read(socket_, buffer_, req_,
|
||||
boost::asio::bind_executor(strand_, [ this, self = shared_from_this() ](beast::error_code ec, std::size_t bytes) { on_read(ec, bytes); }));
|
||||
}
|
||||
|
||||
|
||||
|
@ -305,25 +310,44 @@ void ControlSessionHttp::stop()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void ControlSessionHttp::sendAsync(const std::string& message)
|
||||
{
|
||||
if (!ws_)
|
||||
return;
|
||||
|
||||
auto self(shared_from_this());
|
||||
ws_->async_write(boost::asio::buffer(message), [self](std::error_code ec, std::size_t length) {
|
||||
if (ec)
|
||||
strand_.post([this, message]() {
|
||||
messages_.emplace_back(message);
|
||||
if (messages_.size() > 1)
|
||||
{
|
||||
LOG(ERROR) << "Error while writing to control socket: " << ec.message() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(DEBUG) << "Wrote " << length << " bytes to control socket\n";
|
||||
LOG(DEBUG) << "HTTP session outstanding async_writes: " << messages_.size() << "\n";
|
||||
return;
|
||||
}
|
||||
send_next();
|
||||
});
|
||||
}
|
||||
|
||||
void ControlSessionHttp::send_next()
|
||||
{
|
||||
if (!ws_)
|
||||
return;
|
||||
|
||||
auto self(shared_from_this());
|
||||
auto message = messages_.front();
|
||||
ws_->async_write(boost::asio::buffer(message), boost::asio::bind_executor(strand_, [this, self](std::error_code ec, std::size_t length) {
|
||||
messages_.pop_front();
|
||||
if (ec)
|
||||
{
|
||||
LOG(ERROR) << "Error while writing to web socket: " << ec.message() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(DEBUG) << "Wrote " << length << " bytes to web socket\n";
|
||||
}
|
||||
if (!messages_.empty())
|
||||
send_next();
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
bool ControlSessionHttp::send(const std::string& message)
|
||||
{
|
||||
|
@ -351,7 +375,8 @@ void ControlSessionHttp::do_read_ws()
|
|||
{
|
||||
// Read a message into our buffer
|
||||
auto self(shared_from_this());
|
||||
ws_->async_read(buffer_, [this, self](beast::error_code ec, std::size_t bytes_transferred) { on_read_ws(ec, bytes_transferred); });
|
||||
ws_->async_read(
|
||||
buffer_, boost::asio::bind_executor(strand_, [this, self](beast::error_code ec, std::size_t bytes_transferred) { on_read_ws(ec, bytes_transferred); }));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue