1 // 2 // Copyright (c) 2016-2019 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, 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 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> 31 32 // Sends a WebSocket message and prints the response main(int argc,char ** argv)33int 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 } 46 std::string host = argv[1]; 47 auto const port = argv[2]; 48 auto const text = argv[3]; 49 50 // The io_context is required for all I/O 51 net::io_context ioc; 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 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()); 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 })); 76 77 // Perform the websocket handshake 78 ws.handshake(host, "/"); 79 80 // Send the message 81 ws.write(net::buffer(std::string(text))); 82 83 // This buffer will hold the incoming message 84 beast::flat_buffer buffer; 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 94 // The make_printable() function helps print a ConstBufferSequence 95 std::cout << beast::make_printable(buffer.data()) << std::endl; 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 //] 106