View in context in the libbitcoin Slack #general mirror.
// Channel... this declares all state maintained by the derived http channel (channel_client).
subscriber<http_string_request> subscriber_;
http_flat_buffer request_buffer_;
bool reading_{};
// Channel... this listens for a request object (string).
void channel_client::read_request() NOEXCEPT
{
if (stopped() || paused() || reading_)
return;
// HTTP is half duplex.
reading_ = true;
// Use shared pointer to capture request in completion handler.
const auto request = to_shared<http_string_request>();
// Post handle_read_request to strand upon stop, error, or buffer full.
read(request_buffer_, *request,
std::bind(&channel_client::handle_read_request,
shared_from_base<channel_client>(), _1, _2, request));
}
// Channel... this notifies subscribers of the request, stopping channel on read failure.
void channel_client::handle_read_request(const code& ec, size_t,
const http_string_request_ptr& request) NOEXCEPT
{
BC_ASSERT_MSG(stranded(), "strand");
if (stopped())
return;
if (ec)
{
stop(ec);
return;
}
// HTTP is half duplex.
reading_ = false;
subscriber_.notify(error::success, *request);
}
// Channel... this sends a response object (string, file, or binary), stopping channel on send failure.
template <class Message>
void send(Message&& response, result_handler&& handler) NOEXCEPT
{
BC_ASSERT_MSG(stranded(), "strand");
const auto ptr = system::make_shared(std::forward<Message>(response));
// Use shared pointer to capture response in completion intermediate handler.
auto complete = [self = shared_from_base<channel_client>(), ptr,
handle = std::move(handler)](const code& ec, size_t) NOEXCEPT
{
if (ec) self->stop(ec);
handle(ec);
};
write(*ptr, std::move(complete));
} (edited)