Skip to content

Commit 0f0b98e

Browse files
committed
[FOLD]
1 parent 9efd097 commit 0f0b98e

File tree

3 files changed

+238
-0
lines changed

3 files changed

+238
-0
lines changed

include/boost/ws_io/client.hpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/ws_io
8+
//
9+
10+
#ifndef BOOST_WS_IO_CLIENT_HPP
11+
#define BOOST_WS_IO_CLIENT_HPP
12+
13+
#include <boost/ws_io/detail/config.hpp>
14+
#include <boost/http_proto/context.hpp>
15+
#include <boost/asio/async_result.hpp>
16+
#include <boost/asio/default_completion_token.hpp>
17+
#include <boost/core/detail/string_view.hpp>
18+
#include <type_traits>
19+
20+
namespace boost {
21+
namespace ws_io {
22+
23+
/** A websocket client session
24+
*/
25+
template<
26+
class AsyncStream>
27+
class client
28+
{
29+
public:
30+
using stream_type = AsyncStream;
31+
using executor_type = decltype(
32+
std::declval<AsyncStream&>().get_executor());
33+
34+
client(
35+
AsyncStream& stream,
36+
http_proto::context& ctx);
37+
38+
/** Perform the websocket handshake
39+
*/
40+
template<
41+
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(
42+
::boost::beast::error_code,
43+
::boost::http_proto::response_view)) HandshakeHandler =
44+
asio::default_completion_token_t<executor_type>
45+
>
46+
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler, void(
47+
::boost::beast::error_code,
48+
::boost::http_proto::response_view))
49+
async_handshake(
50+
core::string_view host,
51+
core::string_view target,
52+
HandshakeHandler&& handler =
53+
asio::default_completion_token_t<executor_type>{});
54+
55+
AsyncStream&
56+
next_layer() noexcept
57+
{
58+
return stream_;
59+
}
60+
61+
private:
62+
template<class Handler>
63+
class handshake_op;
64+
struct run_handshake_op;
65+
66+
AsyncStream& stream_;
67+
http_proto::context& ctx_;
68+
};
69+
70+
} // ws_io
71+
} // boost
72+
73+
#include <boost/ws_io/impl/client.hpp>
74+
75+
#endif
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco ([email protected])
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/ws_io
8+
//
9+
10+
#ifndef BOOST_WS_IO_IMPL_CLIENT_HPP
11+
#define BOOST_WS_IO_IMPL_CLIENT_HPP
12+
13+
#include <boost/asio/async_result.hpp>
14+
#include <boost/http_proto/response_view.hpp>
15+
#include <boost/asio/coroutine.hpp>
16+
17+
namespace boost {
18+
namespace ws_io {
19+
20+
//------------------------------------------------
21+
22+
template<class AsyncStream>
23+
template<class Handler>
24+
class client<AsyncStream>::
25+
handshake_op
26+
: public asio::coroutine
27+
{
28+
client<AsyncStream>& cs_;
29+
Handler h_;
30+
31+
public:
32+
template<class Handler_>
33+
handshake_op(
34+
client<AsyncStream>& cs,
35+
Handler_&& h,
36+
core::string_view host,
37+
core::string_view target)
38+
: cs_(cs)
39+
, h_(std::forward<Handler_>(h))
40+
{
41+
}
42+
43+
};
44+
45+
//------------------------------------------------
46+
47+
template<class AsyncStream>
48+
struct client<AsyncStream>::
49+
run_handshake_op
50+
{
51+
client<AsyncStream>& self;
52+
53+
using executor_type = typename
54+
client<AsyncStream>::executor_type;
55+
56+
executor_type
57+
get_executor() const noexcept
58+
{
59+
return self.next_layer().get_executor();
60+
}
61+
62+
template<class HandshakeHandler>
63+
void operator()(
64+
HandshakeHandler&& h,
65+
core::string_view host,
66+
core::string_view target
67+
/*,request_type&& req
68+
,detail::sec_ws_key_type key
69+
,response_type* res_p*/
70+
)
71+
{
72+
handshake_op<typename std::decay<
73+
HandshakeHandler>::type>(
74+
self,
75+
std::forward<HandshakeHandler>(h),
76+
host,
77+
target);
78+
}
79+
};
80+
81+
//------------------------------------------------
82+
83+
template<class AsyncStream>
84+
client<AsyncStream>::
85+
client(
86+
AsyncStream& stream,
87+
http_proto::context& ctx)
88+
: stream_(stream)
89+
, ctx_(ctx)
90+
{
91+
}
92+
93+
template<class AsyncStream>
94+
template<
95+
BOOST_ASIO_COMPLETION_TOKEN_FOR(void(
96+
::boost::beast::error_code,
97+
::boost::http_proto::response_view)) HandshakeHandler>
98+
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(HandshakeHandler, void(
99+
::boost::beast::error_code,
100+
::boost::http_proto::response_view))
101+
client<AsyncStream>::
102+
async_handshake(
103+
core::string_view host,
104+
core::string_view target,
105+
HandshakeHandler&& handler)
106+
{
107+
return asio::async_initiate<
108+
HandshakeHandler,
109+
void(system::error_code, http_proto::response_view)>(
110+
run_handshake_op{*this},
111+
handler,
112+
host,
113+
target);
114+
}
115+
116+
} // ws_io
117+
} // boost
118+
119+
#endif

test/unit/client.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
3+
//
4+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// Official repository: https://github.com/cppalliance/ws_io
8+
//
9+
10+
#include <boost/ws_io/client.hpp>
11+
#include <boost/http_proto/context.hpp>
12+
#include <boost/http_proto/parser.hpp>
13+
#include "test/unit/server.hpp"
14+
#include "test_suite.hpp"
15+
16+
namespace boost {
17+
namespace ws_io {
18+
19+
struct client_test
20+
{
21+
void
22+
run()
23+
{
24+
http_proto::context ctx;
25+
http_proto::parser::config_base cfg;
26+
http_proto::install_parser_service(ctx, cfg);
27+
28+
test::server srv;
29+
auto sock = srv.connect();
30+
client<test::socket_type> cs(sock, ctx);
31+
cs.async_handshake(
32+
"localhost",
33+
"/",
34+
test::success_handler());
35+
srv.run();
36+
}
37+
};
38+
39+
TEST_SUITE(
40+
client_test,
41+
"boost.ws_io.client");
42+
43+
} // ws_io
44+
} // boost

0 commit comments

Comments
 (0)