1#ifdef JOEDB_HAS_WEBSOCKETS
4#include <boost/asio/ip/tcp.hpp>
5#include <boost/asio/connect.hpp>
6#include <boost/asio/ssl.hpp>
7#include <boost/beast/websocket.hpp>
8#include <boost/beast/websocket/ssl.hpp>
9#include <boost/certify/https_verification.hpp>
10#include <boost/certify/extensions.hpp>
16 class Websocket_Channel
19 boost::asio::io_context io_context;
20 boost::asio::ssl::context ssl_context;
22 boost::beast::websocket::stream
24 boost::asio::ssl::stream
26 boost::asio::ip::tcp::socket
34 const std::string &host,
35 const std::string &port,
36 const std::string &path
38 ssl_context(boost::asio::ssl::context::tlsv12_client),
39 ws(io_context, ssl_context)
41 ssl_context.set_verify_mode
43 boost::asio::ssl::context::verify_peer |
44 boost::asio::ssl::context::verify_fail_if_no_peer_cert
47 ssl_context.set_default_verify_paths();
49 boost::certify::enable_native_https_server_verification(ssl_context);
50 boost::certify::set_server_hostname(ws.next_layer(), host);
51 boost::certify::sni_hostname(ws.next_layer(), host);
53 const auto endpoint = boost::asio::connect
55 boost::beast::get_lowest_layer(ws),
56 boost::asio::ip::tcp::resolver(io_context).resolve(host, port)
59 ws.next_layer().handshake(boost::asio::ssl::stream_base::client);
63 boost::beast::get_lowest_layer(ws).set_option
65 boost::asio::ip::tcp::no_delay(
true)
68 boost::beast::get_lowest_layer(ws).set_option
70 boost::asio::socket_base::keep_alive(
true)
75 host +
":" + std::to_string(endpoint.port()),
80 size_t write_some(
const char *data,
size_t size)
82 return ws.write(boost::asio::buffer(data, size));
85 size_t read_some(
char *data,
size_t size)
87 return ws.read_some(boost::asio::buffer(data, size));
94 boost::system::error_code ec;
95 ws.close(boost::beast::websocket::close_code::normal, ec);
106 const std::string &host,
107 const std::string &port,
108 const std::string &path
116 return p->write_some(data, size);
121 return p->read_some(data, size);
Channel to communicate with a (secure) Websocket.
~Websocket_Channel() override
size_t write_some(const char *data, size_t size) override
Websocket_Channel(const std::string &host, const std::string &port, const std::string &path)
size_t read_some(char *data, size_t size) override