// // 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(boost::asio::ip::tcp::resolver::query{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& req) { req.insert(http::field::sec_websocket_protocol, "xmpp;ws-chat"); }); //] //[ws_snippet_10 response_type res; ws.handshake(res, "localhost", "/"); if(! res.exists(http::field::sec_websocket_protocol)) throw std::invalid_argument("missing subprotocols"); //] //[ws_snippet_11 ws.accept(); //] //[ws_snippet_12 ws.accept_ex( [](response_type& res) { res.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; opcode op; ws.read(op, buffer); ws.binary(op == opcode::binary); ws.write(buffer.data()); buffer.consume(buffer.size()); //] } { stream ws{ios}; //[ws_snippet_16 multi_buffer buffer; frame_info fi; for(;;) { ws.read_frame(fi, buffer); if(fi.fin) break; } ws.binary(fi.op == opcode::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.ping_callback( [](bool is_pong, ping_data const& payload) { // Do something with the payload }); //] //[ws_snippet_18 ws.close(close_code::normal); //] //[ws_snippet_19 ws.auto_fragment(true); ws.write_buffer_size(16384); //] //[ws_snippet_20 opcode op; multi_buffer buffer; ws.async_read(op, buffer, [](error_code ec) { // Do something with the buffer }); //] } } // fxx() //[ws_snippet_21 void echo(stream& ws, multi_buffer& buffer, boost::asio::yield_context yield) { opcode op; ws.async_read(op, buffer, yield); std::future fut = ws.async_write(buffer.data(), boost::asio::use_future); } //] } // doc_ws_snippets