]>
Commit | Line | Data |
---|---|---|
b32b8144 | 1 | // |
92f5a8d4 | 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) |
b32b8144 FG |
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, synchronous | |
13 | // | |
14 | //------------------------------------------------------------------------------ | |
15 | ||
16 | //[example_websocket_client | |
17 | ||
18 | #include <boost/beast/core.hpp> | |
19 | #include <boost/beast/websocket.hpp> | |
20 | #include <boost/asio/connect.hpp> | |
21 | #include <boost/asio/ip/tcp.hpp> | |
22 | #include <cstdlib> | |
23 | #include <iostream> | |
24 | #include <string> | |
25 | ||
92f5a8d4 TL |
26 | namespace beast = boost::beast; // from <boost/beast.hpp> |
27 | namespace http = beast::http; // from <boost/beast/http.hpp> | |
28 | namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp> | |
29 | namespace net = boost::asio; // from <boost/asio.hpp> | |
30 | using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp> | |
b32b8144 FG |
31 | |
32 | // Sends a WebSocket message and prints the response | |
33 | int main(int argc, char** argv) | |
34 | { | |
35 | try | |
36 | { | |
37 | // Check command line arguments. | |
38 | if(argc != 4) | |
39 | { | |
40 | std::cerr << | |
41 | "Usage: websocket-client-sync <host> <port> <text>\n" << | |
42 | "Example:\n" << | |
43 | " websocket-client-sync echo.websocket.org 80 \"Hello, world!\"\n"; | |
44 | return EXIT_FAILURE; | |
45 | } | |
f67539c2 TL |
46 | std::string host = argv[1]; |
47 | auto const port = argv[2]; | |
48 | auto const text = argv[3]; | |
b32b8144 FG |
49 | |
50 | // The io_context is required for all I/O | |
92f5a8d4 | 51 | net::io_context ioc; |
b32b8144 FG |
52 | |
53 | // These objects perform our I/O | |
54 | tcp::resolver resolver{ioc}; | |
55 | websocket::stream<tcp::socket> ws{ioc}; | |
56 | ||
57 | // Look up the domain name | |
58 | auto const results = resolver.resolve(host, port); | |
59 | ||
60 | // Make the connection on the IP address we get from a lookup | |
f67539c2 TL |
61 | auto ep = net::connect(ws.next_layer(), results); |
62 | ||
63 | // Update the host_ string. This will provide the value of the | |
64 | // Host HTTP header during the WebSocket handshake. | |
65 | // See https://tools.ietf.org/html/rfc7230#section-5.4 | |
66 | host += ':' + std::to_string(ep.port()); | |
92f5a8d4 TL |
67 | |
68 | // Set a decorator to change the User-Agent of the handshake | |
69 | ws.set_option(websocket::stream_base::decorator( | |
70 | [](websocket::request_type& req) | |
71 | { | |
72 | req.set(http::field::user_agent, | |
73 | std::string(BOOST_BEAST_VERSION_STRING) + | |
74 | " websocket-client-coro"); | |
75 | })); | |
b32b8144 FG |
76 | |
77 | // Perform the websocket handshake | |
78 | ws.handshake(host, "/"); | |
79 | ||
80 | // Send the message | |
92f5a8d4 | 81 | ws.write(net::buffer(std::string(text))); |
b32b8144 FG |
82 | |
83 | // This buffer will hold the incoming message | |
92f5a8d4 | 84 | beast::flat_buffer buffer; |
b32b8144 FG |
85 | |
86 | // Read a message into our buffer | |
87 | ws.read(buffer); | |
88 | ||
89 | // Close the WebSocket connection | |
90 | ws.close(websocket::close_code::normal); | |
91 | ||
92 | // If we get here then the connection is closed gracefully | |
93 | ||
92f5a8d4 TL |
94 | // The make_printable() function helps print a ConstBufferSequence |
95 | std::cout << beast::make_printable(buffer.data()) << std::endl; | |
b32b8144 FG |
96 | } |
97 | catch(std::exception const& e) | |
98 | { | |
99 | std::cerr << "Error: " << e.what() << std::endl; | |
100 | return EXIT_FAILURE; | |
101 | } | |
102 | return EXIT_SUCCESS; | |
103 | } | |
104 | ||
105 | //] |