]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/beast/example/websocket/client/async/websocket_client_async.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / beast / example / websocket / client / async / websocket_client_async.cpp
1 //
2 // Copyright (c) 2016-2017 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/boostorg/beast
8 //
9
10 //------------------------------------------------------------------------------
11 //
12 // Example: WebSocket client, asynchronous
13 //
14 //------------------------------------------------------------------------------
15
16 #include <boost/beast/core.hpp>
17 #include <boost/beast/websocket.hpp>
18 #include <boost/asio/connect.hpp>
19 #include <boost/asio/ip/tcp.hpp>
20 #include <cstdlib>
21 #include <functional>
22 #include <iostream>
23 #include <memory>
24 #include <string>
25
26 using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
27 namespace websocket = boost::beast::websocket; // from <boost/beast/websocket.hpp>
28
29 //------------------------------------------------------------------------------
30
31 // Report a failure
32 void
33 fail(boost::system::error_code ec, char const* what)
34 {
35 std::cerr << what << ": " << ec.message() << "\n";
36 }
37
38 // Sends a WebSocket message and prints the response
39 class session : public std::enable_shared_from_this<session>
40 {
41 tcp::resolver resolver_;
42 websocket::stream<tcp::socket> ws_;
43 boost::beast::multi_buffer buffer_;
44 std::string host_;
45 std::string text_;
46
47 public:
48 // Resolver and socket require an io_context
49 explicit
50 session(boost::asio::io_context& ioc)
51 : resolver_(ioc)
52 , ws_(ioc)
53 {
54 }
55
56 // Start the asynchronous operation
57 void
58 run(
59 char const* host,
60 char const* port,
61 char const* text)
62 {
63 // Save these for later
64 host_ = host;
65 text_ = text;
66
67 // Look up the domain name
68 resolver_.async_resolve(
69 host,
70 port,
71 std::bind(
72 &session::on_resolve,
73 shared_from_this(),
74 std::placeholders::_1,
75 std::placeholders::_2));
76 }
77
78 void
79 on_resolve(
80 boost::system::error_code ec,
81 tcp::resolver::results_type results)
82 {
83 if(ec)
84 return fail(ec, "resolve");
85
86 // Make the connection on the IP address we get from a lookup
87 boost::asio::async_connect(
88 ws_.next_layer(),
89 results.begin(),
90 results.end(),
91 std::bind(
92 &session::on_connect,
93 shared_from_this(),
94 std::placeholders::_1));
95 }
96
97 void
98 on_connect(boost::system::error_code ec)
99 {
100 if(ec)
101 return fail(ec, "connect");
102
103 // Perform the websocket handshake
104 ws_.async_handshake(host_, "/",
105 std::bind(
106 &session::on_handshake,
107 shared_from_this(),
108 std::placeholders::_1));
109 }
110
111 void
112 on_handshake(boost::system::error_code ec)
113 {
114 if(ec)
115 return fail(ec, "handshake");
116
117 // Send the message
118 ws_.async_write(
119 boost::asio::buffer(text_),
120 std::bind(
121 &session::on_write,
122 shared_from_this(),
123 std::placeholders::_1,
124 std::placeholders::_2));
125 }
126
127 void
128 on_write(
129 boost::system::error_code ec,
130 std::size_t bytes_transferred)
131 {
132 boost::ignore_unused(bytes_transferred);
133
134 if(ec)
135 return fail(ec, "write");
136
137 // Read a message into our buffer
138 ws_.async_read(
139 buffer_,
140 std::bind(
141 &session::on_read,
142 shared_from_this(),
143 std::placeholders::_1,
144 std::placeholders::_2));
145 }
146
147 void
148 on_read(
149 boost::system::error_code ec,
150 std::size_t bytes_transferred)
151 {
152 boost::ignore_unused(bytes_transferred);
153
154 if(ec)
155 return fail(ec, "read");
156
157 // Close the WebSocket connection
158 ws_.async_close(websocket::close_code::normal,
159 std::bind(
160 &session::on_close,
161 shared_from_this(),
162 std::placeholders::_1));
163 }
164
165 void
166 on_close(boost::system::error_code ec)
167 {
168 if(ec)
169 return fail(ec, "close");
170
171 // If we get here then the connection is closed gracefully
172
173 // The buffers() function helps print a ConstBufferSequence
174 std::cout << boost::beast::buffers(buffer_.data()) << std::endl;
175 }
176 };
177
178 //------------------------------------------------------------------------------
179
180 int main(int argc, char** argv)
181 {
182 // Check command line arguments.
183 if(argc != 4)
184 {
185 std::cerr <<
186 "Usage: websocket-client-async <host> <port> <text>\n" <<
187 "Example:\n" <<
188 " websocket-client-async echo.websocket.org 80 \"Hello, world!\"\n";
189 return EXIT_FAILURE;
190 }
191 auto const host = argv[1];
192 auto const port = argv[2];
193 auto const text = argv[3];
194
195 // The io_context is required for all I/O
196 boost::asio::io_context ioc;
197
198 // Launch the asynchronous operation
199 std::make_shared<session>(ioc)->run(host, port, text);
200
201 // Run the I/O service. The call will return when
202 // the get operation is complete.
203 ioc.run();
204
205 return EXIT_SUCCESS;
206 }