// // Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include #include #include #include #include #include #include #include //[ws_snippet_1 #include using namespace beast::websocket; //] using namespace beast; namespace doc_ws_snippets { void fxx() { boost::asio::io_service ios; boost::asio::io_service::work work{ios}; std::thread t{[&](){ ios.run(); }}; error_code ec; boost::asio::ip::tcp::socket sock{ios}; { //[ws_snippet_2 stream ws{ios}; //] } { //[ws_snippet_3 stream ws{std::move(sock)}; //] } { //[ws_snippet_4 stream ws{sock}; //] //[ws_snippet_5 ws.next_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_send); //] } { //[ws_snippet_6 std::string const host = "mywebapp.com"; boost::asio::ip::tcp::resolver r{ios}; stream ws{ios}; boost::asio::connect(ws.next_layer(), r.resolve({host, "ws"})); //] } { //[ws_snippet_7 boost::asio::ip::tcp::acceptor acceptor{ios}; stream ws{acceptor.get_io_service()}; acceptor.accept(ws.next_layer()); //] } { stream ws{ios}; //[ws_snippet_8 ws.handshake("localhost", "/"); //] //[ws_snippet_9 ws.handshake_ex("localhost", "/", [](request_type& m) { m.insert(http::field::sec_websocket_protocol, "xmpp;ws-chat"); }); //] //[ws_snippet_10 response_type res; ws.handshake(res, "localhost", "/"); if(! res.count(http::field::sec_websocket_protocol)) throw std::invalid_argument("missing subprotocols"); //] //[ws_snippet_11 ws.accept(); //] //[ws_snippet_12 ws.accept_ex( [](response_type& m) { m.insert(http::field::server, "MyServer"); }); //] } { //[ws_snippet_13] // Buffer required for reading HTTP messages flat_buffer buffer; // Read the HTTP request ourselves http::request req; http::read(sock, buffer, req); // See if its a WebSocket upgrade request if(websocket::is_upgrade(req)) { // Construct the stream, transferring ownership of the socket stream ws{std::move(sock)}; // Accept the request from our message. Clients SHOULD NOT // begin sending WebSocket frames until the server has // provided a response, but just in case they did, we pass // any leftovers in the buffer to the accept function. // ws.accept(req, buffer.data()); } else { // Its not a WebSocket upgrade, so // handle it like a normal HTTP request. } //] } { stream ws{ios}; //[ws_snippet_14 // Read into our buffer until we reach the end of the HTTP request. // No parsing takes place here, we are just accumulating data. boost::asio::streambuf buffer; boost::asio::read_until(sock, buffer, "\r\n\r\n"); // Now accept the connection, using the buffered data. ws.accept(buffer.data()); //] } { stream ws{ios}; //[ws_snippet_15 multi_buffer buffer; ws.read(buffer); ws.text(ws.got_text()); ws.write(buffer.data()); buffer.consume(buffer.size()); //] } { stream ws{ios}; //[ws_snippet_16 multi_buffer buffer; for(;;) if(ws.read_frame(buffer)) break; ws.binary(ws.got_binary()); consuming_buffers cb{buffer.data()}; for(;;) { using boost::asio::buffer_size; if(buffer_size(cb) > 512) { ws.write_frame(false, buffer_prefix(512, cb)); cb.consume(512); } else { ws.write_frame(true, cb); break; } } //] } { stream ws{ios}; //[ws_snippet_17 ws.control_callback( [](frame_type kind, string_view payload) { // Do something with the payload boost::ignore_unused(kind, payload); }); //] //[ws_snippet_18 ws.close(close_code::normal); //] //[ws_snippet_19 ws.auto_fragment(true); ws.write_buffer_size(16384); //] //[ws_snippet_20 multi_buffer buffer; ws.async_read(buffer, [](error_code) { // Do something with the buffer }); //] } } // fxx() // workaround for https://github.com/chriskohlhoff/asio/issues/112 #ifdef _MSC_VER //[ws_snippet_21 void echo(stream& ws, multi_buffer& buffer, boost::asio::yield_context yield) { ws.async_read(buffer, yield); std::future fut = ws.async_write(buffer.data(), boost::asio::use_future); } //] #endif } // doc_ws_snippets //------------------------------------------------------------------------------ #if BEAST_USE_OPENSSL //[wss_snippet_1 #include #include //] namespace doc_wss_snippets { void fxx() { boost::asio::io_service ios; boost::asio::io_service::work work{ios}; std::thread t{[&](){ ios.run(); }}; error_code ec; boost::asio::ip::tcp::socket sock{ios}; { //[wss_snippet_2 boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23}; stream> wss{ios, ctx}; //] } { //[wss_snippet_3 boost::asio::ip::tcp::endpoint ep; boost::asio::ssl::context ctx{boost::asio::ssl::context::sslv23}; stream> ws{ios, ctx}; // connect the underlying TCP/IP socket ws.next_layer().next_layer().connect(ep); // perform SSL handshake ws.next_layer().handshake(boost::asio::ssl::stream_base::client); // perform WebSocket handshake ws.handshake("localhost", "/"); //] } } // fxx() } // doc_wss_snippets #endif