mirror of
https://github.com/boostorg/redis.git
synced 2026-01-19 04:42:09 +00:00
Remove Command template parameter from request.
This commit is contained in:
@@ -32,7 +32,7 @@ namespace aedis {
|
||||
*
|
||||
* https://redis.io/docs/reference/sentinel-clients
|
||||
*/
|
||||
template <class Command, class AsyncReadWriteStream = boost::asio::ip::tcp::socket>
|
||||
template <class AsyncReadWriteStream = boost::asio::ip::tcp::socket>
|
||||
class connection {
|
||||
public:
|
||||
/// Executor type.
|
||||
@@ -41,9 +41,6 @@ public:
|
||||
/// Type of the last layer
|
||||
using next_layer_type = AsyncReadWriteStream;
|
||||
|
||||
/// Type of requests used by the connection.
|
||||
using request_type = resp3::request<Command>;
|
||||
|
||||
using default_completion_token_type = boost::asio::default_completion_token_t<executor_type>;
|
||||
|
||||
/** @brief Configuration parameters.
|
||||
@@ -121,7 +118,7 @@ public:
|
||||
* error::idle_timeout.
|
||||
*
|
||||
* @li Starts the healthy check operation that sends
|
||||
* redis::command::ping to Redis with a frequency equal to
|
||||
* command::ping to Redis with a frequency equal to
|
||||
* connection::config::ping_interval.
|
||||
*
|
||||
* In addition to the callbacks mentioned above, the read
|
||||
@@ -170,7 +167,7 @@ public:
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code)
|
||||
>(detail::run_op<connection, Command>{this, host, port}, token, resv_);
|
||||
>(detail::run_op<connection>{this, host, port}, token, resv_);
|
||||
}
|
||||
|
||||
/** @brief Asynchrnously schedules a command for execution.
|
||||
@@ -179,7 +176,7 @@ public:
|
||||
class Adapter = detail::response_traits<void>::adapter_type,
|
||||
class CompletionToken = default_completion_token_type>
|
||||
auto async_exec(
|
||||
request_type const& req,
|
||||
resp3::request const& req,
|
||||
Adapter adapter = aedis::adapt(),
|
||||
CompletionToken token = CompletionToken{})
|
||||
{
|
||||
@@ -202,7 +199,7 @@ public:
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code, std::size_t)
|
||||
>(detail::read_push_op<connection, Adapter, Command>{this, adapter}, token, resv_);
|
||||
>(detail::read_push_op<connection, Adapter>{this, adapter}, token, resv_);
|
||||
}
|
||||
|
||||
/** @brief Closes the connection with the database.
|
||||
@@ -228,10 +225,10 @@ public:
|
||||
private:
|
||||
using time_point_type = std::chrono::time_point<std::chrono::steady_clock>;
|
||||
|
||||
template <class T, class U, class V> friend struct detail::read_push_op;
|
||||
template <class T, class U> friend struct detail::reader_op;
|
||||
template <class T, class U> friend struct detail::ping_op;
|
||||
template <class T, class U> friend struct detail::run_op;
|
||||
template <class T, class U> friend struct detail::read_push_op;
|
||||
template <class T> friend struct detail::reader_op;
|
||||
template <class T> friend struct detail::ping_op;
|
||||
template <class T> friend struct detail::run_op;
|
||||
template <class T, class U> friend struct detail::exec_op;
|
||||
template <class T> friend struct detail::exec_internal_op;
|
||||
template <class T> friend struct detail::writer_op;
|
||||
@@ -246,7 +243,7 @@ private:
|
||||
bool stop = false;
|
||||
};
|
||||
|
||||
void add_request(request_type const& req)
|
||||
void add_request(resp3::request const& req)
|
||||
{
|
||||
BOOST_ASSERT(!req.payload().empty());
|
||||
auto const can_write = reqs_.empty();
|
||||
@@ -298,7 +295,7 @@ private:
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code)
|
||||
>(detail::reader_op<connection, Command>{this}, token, resv_.get_executor());
|
||||
>(detail::reader_op<connection>{this}, token, resv_.get_executor());
|
||||
}
|
||||
|
||||
template <class CompletionToken = default_completion_token_type>
|
||||
@@ -328,7 +325,7 @@ private:
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code)
|
||||
>(detail::ping_op<connection, Command>{this}, token, resv_);
|
||||
>(detail::ping_op<connection>{this}, token, resv_);
|
||||
}
|
||||
|
||||
template <class CompletionToken = default_completion_token_type>
|
||||
@@ -343,7 +340,7 @@ private:
|
||||
|
||||
template <class CompletionToken = default_completion_token_type>
|
||||
auto async_exec_internal(
|
||||
request_type const& req,
|
||||
resp3::request const& req,
|
||||
CompletionToken token = CompletionToken{})
|
||||
{
|
||||
return boost::asio::async_compose
|
||||
@@ -394,7 +391,7 @@ private:
|
||||
std::string payload_;
|
||||
std::string payload_next_;
|
||||
std::deque<std::shared_ptr<req_info>> reqs_;
|
||||
std::queue<Command> cmds_;
|
||||
std::queue<command> cmds_;
|
||||
std::vector<std::shared_ptr<req_info>> pool_;
|
||||
|
||||
// Last time we received data.
|
||||
@@ -403,7 +400,7 @@ private:
|
||||
// The result of async_resolve.
|
||||
boost::asio::ip::tcp::resolver::results_type endpoints_;
|
||||
|
||||
request_type req_;
|
||||
resp3::request req_;
|
||||
};
|
||||
|
||||
} // aedis
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <aedis/resp3/read.hpp>
|
||||
#include <aedis/resp3/exec.hpp>
|
||||
#include <aedis/resp3/write.hpp>
|
||||
#include <aedis/resp3/request.hpp>
|
||||
|
||||
namespace aedis {
|
||||
namespace detail {
|
||||
@@ -50,7 +51,7 @@ struct connect_with_timeout_op {
|
||||
template <class Conn>
|
||||
struct exec_internal_op {
|
||||
Conn* cli;
|
||||
typename Conn::request_type const* req;
|
||||
resp3::request const* req;
|
||||
boost::asio::coroutine coro;
|
||||
|
||||
template <class Self>
|
||||
@@ -88,7 +89,7 @@ struct resolve_with_timeout_op {
|
||||
}
|
||||
};
|
||||
|
||||
template <class Conn, class Adapter, class Command>
|
||||
template <class Conn, class Adapter>
|
||||
struct read_push_op {
|
||||
Conn* cli;
|
||||
Adapter adapter;
|
||||
@@ -116,7 +117,7 @@ struct read_push_op {
|
||||
resp3::async_read(
|
||||
*cli->socket_,
|
||||
cli->make_dynamic_buffer(),
|
||||
[adpt = adapter](resp3::node<boost::string_view> const& n, boost::system::error_code& ec) mutable { adpt(std::size_t(-1), Command::invalid, n, ec);},
|
||||
[adpt = adapter](resp3::node<boost::string_view> const& n, boost::system::error_code& ec) mutable { adpt(std::size_t(-1), command::invalid, n, ec);},
|
||||
std::move(self));
|
||||
|
||||
cli->wait_read_timer_.cancel_one();
|
||||
@@ -130,7 +131,7 @@ struct read_push_op {
|
||||
template <class Conn, class Adapter>
|
||||
struct exec_op {
|
||||
Conn* cli;
|
||||
typename Conn::request_type const* req;
|
||||
resp3::request const* req;
|
||||
Adapter adapter;
|
||||
std::shared_ptr<typename Conn::req_info> info;
|
||||
std::size_t read_size = 0;
|
||||
@@ -229,7 +230,7 @@ struct exec_op {
|
||||
}
|
||||
};
|
||||
|
||||
template <class Conn, class Command>
|
||||
template <class Conn>
|
||||
struct ping_op {
|
||||
Conn* cli;
|
||||
boost::asio::coroutine coro;
|
||||
@@ -250,7 +251,7 @@ struct ping_op {
|
||||
}
|
||||
|
||||
cli->req_.clear();
|
||||
cli->req_.push(Command::ping);
|
||||
cli->req_.push(command::ping);
|
||||
yield cli->async_exec(cli->req_, aedis::adapt(), std::move(self));
|
||||
if (ec) {
|
||||
self.complete(ec);
|
||||
@@ -343,7 +344,7 @@ struct read_write_check_ping_op {
|
||||
}
|
||||
};
|
||||
|
||||
template <class Conn, class Command>
|
||||
template <class Conn>
|
||||
struct run_op {
|
||||
Conn* cli;
|
||||
boost::string_view host;
|
||||
@@ -375,7 +376,7 @@ struct run_op {
|
||||
}
|
||||
|
||||
cli->req_.clear();
|
||||
cli->req_.push(Command::hello, 3);
|
||||
cli->req_.push(command::hello, 3);
|
||||
cli->check_idle_timer_.expires_after(2 * cli->cfg_.ping_interval);
|
||||
yield cli->async_exec_internal(cli->req_, std::move(self));
|
||||
if (ec) {
|
||||
@@ -450,7 +451,7 @@ struct writer_op {
|
||||
}
|
||||
};
|
||||
|
||||
template <class Conn, class Command>
|
||||
template <class Conn>
|
||||
struct reader_op {
|
||||
Conn* cli;
|
||||
boost::asio::coroutine coro;
|
||||
|
||||
@@ -28,13 +28,12 @@ namespace detail {
|
||||
|
||||
template <
|
||||
class AsyncStream,
|
||||
class Command,
|
||||
class Adapter,
|
||||
class DynamicBuffer
|
||||
>
|
||||
struct exec_op {
|
||||
AsyncStream* socket;
|
||||
request<Command> const* req;
|
||||
request const* req;
|
||||
Adapter adapter;
|
||||
DynamicBuffer dbuf;
|
||||
boost::asio::coroutine coro;
|
||||
@@ -69,14 +68,13 @@ struct exec_op {
|
||||
|
||||
template <
|
||||
class AsyncStream,
|
||||
class Command,
|
||||
class Adapter,
|
||||
class DynamicBuffer,
|
||||
class CompletionToken = boost::asio::default_completion_token_t<typename AsyncStream::executor_type>
|
||||
>
|
||||
auto async_exec(
|
||||
AsyncStream& socket,
|
||||
request<Command> const& req,
|
||||
request const& req,
|
||||
Adapter adapter,
|
||||
DynamicBuffer dbuf,
|
||||
CompletionToken token = CompletionToken{})
|
||||
@@ -84,7 +82,7 @@ auto async_exec(
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code, std::size_t)
|
||||
>(detail::exec_op<AsyncStream, Command, Adapter, DynamicBuffer>
|
||||
>(detail::exec_op<AsyncStream, Adapter, DynamicBuffer>
|
||||
{&socket, &req, adapter, dbuf}, token, socket);
|
||||
}
|
||||
|
||||
@@ -94,14 +92,13 @@ namespace detail {
|
||||
|
||||
template <
|
||||
class AsyncStream,
|
||||
class Command,
|
||||
class Adapter,
|
||||
class DynamicBuffer
|
||||
>
|
||||
struct exec_with_timeout_op {
|
||||
AsyncStream* socket;
|
||||
boost::asio::steady_timer* timer;
|
||||
request<Command> const* req;
|
||||
request const* req;
|
||||
Adapter adapter;
|
||||
DynamicBuffer dbuf;
|
||||
boost::asio::coroutine coro;
|
||||
@@ -154,7 +151,6 @@ struct exec_with_timeout_op {
|
||||
|
||||
template <
|
||||
class AsyncStream,
|
||||
class Command,
|
||||
class Adapter,
|
||||
class DynamicBuffer,
|
||||
class CompletionToken = boost::asio::default_completion_token_t<typename AsyncStream::executor_type>
|
||||
@@ -162,7 +158,7 @@ template <
|
||||
auto async_exec(
|
||||
AsyncStream& socket,
|
||||
boost::asio::steady_timer& timer,
|
||||
request<Command> const& req,
|
||||
request const& req,
|
||||
Adapter adapter,
|
||||
DynamicBuffer dbuf,
|
||||
CompletionToken token = CompletionToken{})
|
||||
@@ -170,7 +166,7 @@ auto async_exec(
|
||||
return boost::asio::async_compose
|
||||
< CompletionToken
|
||||
, void(boost::system::error_code, std::size_t)
|
||||
>(detail::exec_with_timeout_op<AsyncStream, Command, Adapter, DynamicBuffer>
|
||||
>(detail::exec_with_timeout_op<AsyncStream, Adapter, DynamicBuffer>
|
||||
{&socket, &timer, &req, adapter, dbuf}, token, socket, timer);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define AEDIS_RESP3_REQUEST_HPP
|
||||
|
||||
#include <boost/hana.hpp>
|
||||
#include <aedis/command.hpp>
|
||||
#include <aedis/resp3/compose.hpp>
|
||||
|
||||
// NOTE: Consider detecting tuples in the type in the parameter pack
|
||||
@@ -43,7 +44,6 @@ namespace resp3 {
|
||||
* \remarks Non-string types will be converted to string by using \c
|
||||
* to_bulk, which must be made available over ADL.
|
||||
*/
|
||||
template <class Command>
|
||||
class request {
|
||||
public:
|
||||
/// Returns a list of commands contained in this request.
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
* \param args Command arguments.
|
||||
*/
|
||||
template <class... Ts>
|
||||
void push(Command cmd, Ts const&... args)
|
||||
void push(command cmd, Ts const&... args)
|
||||
{
|
||||
using boost::hana::for_each;
|
||||
using boost::hana::make_tuple;
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
* \param end Iterator to the end of the range.
|
||||
*/
|
||||
template <class Key, class ForwardIterator>
|
||||
void push_range2(Command cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
|
||||
void push_range2(command cmd, Key const& key, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
||||
using resp3::type;
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
* \param end Iterator to the end of the range.
|
||||
*/
|
||||
template <class ForwardIterator>
|
||||
void push_range2(Command cmd, ForwardIterator begin, ForwardIterator end)
|
||||
void push_range2(command cmd, ForwardIterator begin, ForwardIterator end)
|
||||
{
|
||||
using value_type = typename std::iterator_traits<ForwardIterator>::value_type;
|
||||
using resp3::type;
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
* Equivalent to the overload taking a range (i.e. send_range2).
|
||||
*/
|
||||
template <class Key, class Range>
|
||||
void push_range(Command cmd, Key const& key, Range const& range)
|
||||
void push_range(command cmd, Key const& key, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
@@ -196,7 +196,7 @@ public:
|
||||
* Equivalent to the overload taking a range (i.e. send_range2).
|
||||
*/
|
||||
template <class Range>
|
||||
void push_range(Command cmd, Range const& range)
|
||||
void push_range(command cmd, Range const& range)
|
||||
{
|
||||
using std::begin;
|
||||
using std::end;
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
using command_info_type = std::pair<Command, std::size_t>;
|
||||
using command_info_type = std::pair<command, std::size_t>;
|
||||
std::string payload_;
|
||||
std::vector<command_info_type> commands_;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace net = boost::asio;
|
||||
namespace adapter = aedis::adapter;
|
||||
using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using connection = aedis::connection<command>;
|
||||
using connection = aedis::connection<>;
|
||||
using node_type = aedis::resp3::node<boost::string_view>;
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
@@ -44,7 +44,7 @@ int main()
|
||||
net::io_context ioc;
|
||||
connection db{ioc};
|
||||
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::ping);
|
||||
req.push(command::incr, "some-key");
|
||||
req.push(command::quit);
|
||||
|
||||
@@ -19,7 +19,7 @@ using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
|
||||
using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::acceptor>;
|
||||
using connection = aedis::connection<command, tcp_socket>;
|
||||
using connection = aedis::connection<tcp_socket>;
|
||||
using response_type = std::vector<aedis::resp3::node<std::string>>;
|
||||
|
||||
class user_session:
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
{
|
||||
try {
|
||||
std::string msg;
|
||||
request<command> req;
|
||||
request req;
|
||||
auto dbuffer = net::dynamic_buffer(msg, 1024);
|
||||
for (;;) {
|
||||
auto const n = co_await net::async_read_until(socket_, dbuffer, "\n");
|
||||
@@ -101,7 +101,7 @@ reader(
|
||||
std::shared_ptr<connection> db,
|
||||
std::shared_ptr<sessions_type> sessions)
|
||||
{
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::subscribe, "channel");
|
||||
co_await db->async_exec(req);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ using boost::optional;
|
||||
using aedis::adapt;
|
||||
using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using connection = aedis::connection<command>;
|
||||
using connection = aedis::connection<>;
|
||||
|
||||
// Response used in this example.
|
||||
using C1 = std::vector<int>;
|
||||
@@ -39,13 +39,13 @@ int main()
|
||||
C2 set {{1, "one"}, {2, "two"}, {3, "three"}, {4, "four"}};
|
||||
C3 map {{"key1", "value1"}, {"key2", "value2"}, {"key3", "value3"}};
|
||||
|
||||
request<command> req1;
|
||||
request req1;
|
||||
req1.push_range(command::rpush, "rpush-key", vec);
|
||||
req1.push_range(command::sadd, "sadd-key", set);
|
||||
req1.push_range(command::hset, "hset-key", map);
|
||||
|
||||
// Request that retrieves the containers.
|
||||
request<command> req2;
|
||||
request req2;
|
||||
req2.push(command::multi);
|
||||
req2.push(command::lrange, "rpush-key", 0, -1);
|
||||
req2.push(command::smembers, "sadd-key");
|
||||
|
||||
@@ -16,14 +16,14 @@ using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
|
||||
using tcp_acceptor = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::acceptor>;
|
||||
using connection = aedis::connection<command, tcp_socket>;
|
||||
using connection = aedis::connection<tcp_socket>;
|
||||
|
||||
net::awaitable<void> echo_loop(tcp_socket socket, std::shared_ptr<connection> db)
|
||||
{
|
||||
try {
|
||||
for (std::string buffer;;) {
|
||||
auto n = co_await net::async_read_until(socket, net::dynamic_buffer(buffer, 1024), "\n");
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::ping, buffer);
|
||||
std::tuple<std::string> resp;
|
||||
co_await db->async_exec(req, adapt(resp));
|
||||
|
||||
@@ -15,14 +15,14 @@ namespace net = boost::asio;
|
||||
using aedis::adapt;
|
||||
using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using connection = aedis::connection<command>;
|
||||
using connection = aedis::connection<>;
|
||||
|
||||
auto handler =[](auto ec, auto...)
|
||||
{ std::cout << ec.message() << std::endl; };
|
||||
|
||||
int main()
|
||||
{
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::ping, "Ping example");
|
||||
req.push(command::quit);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ using aedis::adapt;
|
||||
using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using tcp_socket = net::use_awaitable_t<>::as_default_on_t<net::ip::tcp::socket>;
|
||||
using connection = aedis::connection<command, tcp_socket>;
|
||||
using connection = aedis::connection<tcp_socket>;
|
||||
using response_type = std::vector<aedis::resp3::node<std::string>>;
|
||||
|
||||
/* In this example we send a subscription to a channel and start
|
||||
@@ -36,7 +36,7 @@ using response_type = std::vector<aedis::resp3::node<std::string>>;
|
||||
*/
|
||||
net::awaitable<void> reader(std::shared_ptr<connection> db)
|
||||
{
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::subscribe, "channel");
|
||||
co_await db->async_exec(req);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace resp3 = aedis::resp3;
|
||||
|
||||
using aedis::command;
|
||||
using aedis::resp3::request;
|
||||
using connection = aedis::connection<command>;
|
||||
using connection = aedis::connection<>;
|
||||
using error_code = boost::system::error_code;
|
||||
using net::experimental::as_tuple;
|
||||
using tcp = net::ip::tcp;
|
||||
@@ -72,7 +72,7 @@ void test_quit()
|
||||
net::io_context ioc;
|
||||
auto db = std::make_shared<connection>(ioc);
|
||||
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::quit);
|
||||
db->async_exec(req, aedis::adapt(), [](auto ec, auto r){
|
||||
expect_no_error(ec);
|
||||
@@ -108,7 +108,7 @@ void test_push()
|
||||
net::io_context ioc;
|
||||
auto db = std::make_shared<connection>(ioc);
|
||||
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::subscribe, "channel");
|
||||
req.push(command::quit);
|
||||
|
||||
@@ -132,7 +132,7 @@ void test_push()
|
||||
net::awaitable<void> run5(std::shared_ptr<connection> db)
|
||||
{
|
||||
{
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::quit);
|
||||
db->async_exec(req, aedis::adapt(), [](auto ec, auto){
|
||||
expect_no_error(ec);
|
||||
@@ -143,7 +143,7 @@ net::awaitable<void> run5(std::shared_ptr<connection> db)
|
||||
}
|
||||
|
||||
{
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::quit);
|
||||
db->async_exec(req, aedis::adapt(), [](auto ec, auto){
|
||||
expect_no_error(ec);
|
||||
@@ -176,7 +176,7 @@ void test_idle()
|
||||
net::io_context ioc;
|
||||
auto db = std::make_shared<connection>(ioc, cfg);
|
||||
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::client, "PAUSE", 5000);
|
||||
|
||||
db->async_exec(req, aedis::adapt(), [](auto ec, auto r){
|
||||
|
||||
@@ -30,7 +30,7 @@ int main()
|
||||
net::connect(socket, res);
|
||||
|
||||
// Creates the request and writes to the socket.
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::hello, 3);
|
||||
req.push(command::ping);
|
||||
req.push(command::quit);
|
||||
|
||||
@@ -81,7 +81,7 @@ int main()
|
||||
tcp::socket socket{ioc};
|
||||
net::connect(socket, res);
|
||||
|
||||
request<command> req;
|
||||
request req;
|
||||
req.push(command::hello, 3);
|
||||
req.push(command::command);
|
||||
req.push(command::quit);
|
||||
|
||||
Reference in New Issue
Block a user