3#include "util/WithTimeout.hpp"
4#include "util/requests/Types.hpp"
5#include "util/requests/WsConnection.hpp"
7#include <boost/asio/associated_executor.hpp>
8#include <boost/asio/bind_cancellation_slot.hpp>
9#include <boost/asio/buffer.hpp>
10#include <boost/asio/cancellation_signal.hpp>
11#include <boost/asio/cancellation_type.hpp>
12#include <boost/asio/spawn.hpp>
13#include <boost/asio/steady_timer.hpp>
14#include <boost/beast/core/buffers_to_string.hpp>
15#include <boost/beast/core/error.hpp>
16#include <boost/beast/core/flat_buffer.hpp>
17#include <boost/beast/core/tcp_stream.hpp>
18#include <boost/beast/ssl/ssl_stream.hpp>
19#include <boost/beast/websocket/rfc6455.hpp>
20#include <boost/beast/websocket/stream.hpp>
21#include <boost/beast/websocket/stream_base.hpp>
22#include <boost/system/errc.hpp>
32namespace util::requests::impl {
34template <
typename StreamType>
39 explicit WsConnectionImpl(StreamType ws) : ws_(std::move(ws))
43 std::expected<std::string, RequestError>
45 boost::asio::yield_context yield,
46 std::optional<std::chrono::steady_clock::duration> timeout = std::nullopt
49 boost::beast::error_code errorCode;
50 boost::beast::flat_buffer buffer;
52 auto operation = [&](
auto&& token) { ws_.async_read(buffer, token); };
56 operation(yield[errorCode]);
60 return std::unexpected{
RequestError{
"Read error", errorCode}};
62 return boost::beast::buffers_to_string(std::move(buffer).
data());
65 std::optional<RequestError>
67 std::string
const& message,
68 boost::asio::yield_context yield,
69 std::optional<std::chrono::steady_clock::duration> timeout = std::nullopt
72 boost::beast::error_code errorCode;
73 auto operation = [&](
auto&& token) {
74 ws_.async_write(boost::asio::buffer(message), token);
79 operation(yield[errorCode]);
88 std::optional<RequestError>
90 boost::asio::yield_context yield,
95 boost::beast::websocket::stream_base::timeout wsTimeout{};
96 ws_.get_option(wsTimeout);
97 wsTimeout.handshake_timeout = timeout;
98 ws_.set_option(wsTimeout);
100 boost::beast::error_code errorCode;
101 ws_.async_close(boost::beast::websocket::close_code::normal, yield[errorCode]);
108using PlainWsConnection =
109 WsConnectionImpl<boost::beast::websocket::stream<boost::beast::tcp_stream>>;
110using SslWsConnection = WsConnectionImpl<
111 boost::beast::websocket::stream<boost::asio::ssl::stream<boost::beast::tcp_stream>>>;
Error type for HTTP requests.
Definition Types.hpp:15
Interface for WebSocket connections. It is used to hide SSL and plain connections behind the same int...
Definition WsConnection.hpp:30
static constexpr std::chrono::seconds kDEFAULT_TIMEOUT
Definition WsConnection.hpp:75
std::optional< RequestError > close(boost::asio::yield_context yield, std::chrono::steady_clock::duration const timeout=kDEFAULT_TIMEOUT) override
Close the WebSocket.
Definition WsConnectionImpl.hpp:89
std::optional< RequestError > write(std::string const &message, boost::asio::yield_context yield, std::optional< std::chrono::steady_clock::duration > timeout=std::nullopt) override
Write a message to the WebSocket.
Definition WsConnectionImpl.hpp:66
std::expected< std::string, RequestError > read(boost::asio::yield_context yield, std::optional< std::chrono::steady_clock::duration > timeout=std::nullopt) override
Read a message from the WebSocket.
Definition WsConnectionImpl.hpp:44
This namespace implements the data access layer and related components.
Definition AmendmentCenter.cpp:56
boost::system::error_code withTimeout(Operation &&operation, boost::asio::yield_context yield, std::chrono::steady_clock::duration timeout)
Perform a coroutine operation with a timeout.
Definition WithTimeout.hpp:30