From 0a12426ddcf0f431b56ef73c3e00d1065fdde465 Mon Sep 17 00:00:00 2001 From: Nathan Toone Date: Tue, 11 Feb 2025 18:12:32 -0700 Subject: [PATCH] Update to make WebSocket++ work with modern Asio/Boost MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Back in 2018, a bunch of Asio stuff was deprecated in Asio 1.12.0/Boost 1.66.0 to reflect the Networking TS. Now that it’s been a while, many of these deprecated functions and interfaces have been removed. As of Asio 1.34.0/Boost 1.87.0, WebSocket++ will not function. This commit makes the following changes and allows for functionality modern versions of Asio/Boost: * Use `io_context` instead of `io_service` * Use `basic_waitable_timer::expiry` instead of `basic_waitable_timer::expires_from_now` * Call `asio::post` instead of `io_context::post` * Use `executor_work_guard` instead of `io_context::work` * Use `resolver::resolve` directly instead of creating `resolver::query` * Use `resolver::results_type` instead of `resolver::iterator directly` * Use `max_listen_connextions` instead of `max_connections` * Use `io_context::restart` instead of `io_context::reset` * Use `make_address` instead of `from_string` --- SConstruct | 4 +- docs/faq.dox | 12 +- .../broadcast_server/broadcast_server.cpp | 2 +- examples/debug_client/debug_client.cpp | 2 +- examples/debug_server/debug_server.cpp | 2 +- examples/echo_client/echo_client.cpp | 2 +- examples/echo_server/echo_server.cpp | 2 +- .../echo_server_both/echo_server_both.cpp | 14 +- examples/echo_server_tls/echo_server_tls.cpp | 2 +- .../CMakeLists.txt | 2 +- .../SConscript | 4 +- .../external_io_context.cpp} | 12 +- .../tcp_echo_server.hpp | 12 +- examples/print_client/print_client.cpp | 2 +- .../print_client_tls/print_client_tls.cpp | 2 +- examples/scratch_server/scratch_server.cpp | 2 +- examples/sip_client/sip_client.cpp | 2 +- .../telemetry_client/telemetry_client.cpp | 4 +- .../telemetry_server/telemetry_server.cpp | 2 +- examples/testee_client/testee_client.cpp | 4 +- examples/testee_server/testee_server.cpp | 2 +- roadmap.md | 2 +- test/endpoint/endpoint.cpp | 8 +- test/transport/asio/timers.cpp | 10 +- test/transport/integration.cpp | 27 ++- tutorials/utility_server/step1.cpp | 2 +- tutorials/utility_server/step2.cpp | 2 +- tutorials/utility_server/utility_server.md | 8 +- websocketpp/roles/server_endpoint.hpp | 4 +- websocketpp/transport/asio/base.hpp | 2 +- websocketpp/transport/asio/connection.hpp | 44 ++-- websocketpp/transport/asio/endpoint.hpp | 198 +++++++++--------- websocketpp/transport/asio/security/none.hpp | 16 +- websocketpp/transport/asio/security/tls.hpp | 20 +- websocketpp/transport/debug/endpoint.hpp | 2 +- websocketpp/transport/iostream/endpoint.hpp | 2 +- websocketpp/transport/stub/endpoint.hpp | 2 +- 37 files changed, 217 insertions(+), 224 deletions(-) rename examples/{external_io_service => external_io_context}/CMakeLists.txt (87%) rename examples/{external_io_service => external_io_context}/SConscript (72%) rename examples/{external_io_service/external_io_service.cpp => external_io_context/external_io_context.cpp} (93%) rename examples/{external_io_service => external_io_context}/tcp_echo_server.hpp (92%) diff --git a/SConstruct b/SConstruct index c5ae19369..f87e4e8b9 100644 --- a/SConstruct +++ b/SConstruct @@ -273,8 +273,8 @@ subprotocol_server = SConscript('#/examples/subprotocol_server/SConscript',varia # telemetry_server telemetry_server = SConscript('#/examples/telemetry_server/SConscript',variant_dir = builddir + 'telemetry_server',duplicate = 0) -# external_io_service -external_io_service = SConscript('#/examples/external_io_service/SConscript',variant_dir = builddir + 'external_io_service',duplicate = 0) +# external_io_context +external_io_context = SConscript('#/examples/external_io_context/SConscript',variant_dir = builddir + 'external_io_context',duplicate = 0) if not env['PLATFORM'].startswith('win'): # iostream_server diff --git a/docs/faq.dox b/docs/faq.dox index 9f417ec41..c89e85b61 100644 --- a/docs/faq.dox +++ b/docs/faq.dox @@ -29,19 +29,19 @@ Note: some browsers will allow the connection to continue if they requested a su ### How do I cleanly exit an Asio transport based program -The Asio transport based clients and servers use the Asio library's underlying `io_service` to handle asyncronous networking operations. The standard behavior of the io_service is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following: +The Asio transport based clients and servers use the Asio library's underlying `io_context` to handle asyncronous networking operations. The standard behavior of the io_context is to run until there are no async operations left and then return. WebSocket++, when using the Asio transport, behaves like a standard Asio application. If you want your WebSocket++/Asio based program to stop network operations and cleanly close all sockets you will want to do the following: - For servers, call `websocketpp::transport::asio::endpoint::stop_listening` to initiate the closing of the server listening socket. - For clients, if you have engaged perpetual mode with `websocketpp::transport::asio::endpoint::start_perpetual`, disable it with `websocketpp::transport::asio::endpoint::stop_perpetual`. - For both, run `websocketpp::endpoint::close` or `websocketpp::connection::close` on all currently outstanding connections. This will initiate the WebSocket closing handshake for these connections -- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_service gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_service::run` method will exit cleanly and automatically when all operations are complete. +- Wait. Asio is asyncronous. When the calls to the above methods (stop_listening, close, etc) complete the server *will still be listening*, the connections *will still be active* until the io_context gets around to asyncronously processing the socket and WebSocket protocol closing handshakes. The `io_context::run` method will exit cleanly and automatically when all operations are complete. -__WARNING__: Asio's `io_service` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_service::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_service::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors. +__WARNING__: Asio's `io_context` has a method called `stop`. WebSocket++ wraps this method as `websocketpp::transport::asio::endpoint::stop`. While this operation has a benign sounding name, it is a powerful and destructive operation that should only be used in special cases. If you are using `io_context::stop` or `endpoint::stop` without a very good reason your program is likely broken and may exhibit erratic behavior. Specifically, `io_context::stop` stops the processing of events entirely. This does not give current operations (such as socket closing handshakes) the opportunity to finish. It will leave your sockets in a dangling state that may invoke operating system level timeouts or other errors. __Special cases__: -- If your client uses the `start_perpetual` method it will prevent the io_service from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each. -- If you are using an external io_service and/or are placing non-WebSocket++ operations on the `io_service` those operations may keep the `io_service` open even after all WebSocket++ operations have completed. -- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_service` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_service::work`" cases. +- If your client uses the `start_perpetual` method it will prevent the io_context from exiting even if it has nothing to do. This is useful if you want a client endpoint to idle in the background to allow new connections to be formed on demand rather than generating a new endpoint for each. +- If you are using an external io_context and/or are placing non-WebSocket++ operations on the `io_context` those operations may keep the `io_context` open even after all WebSocket++ operations have completed. +- If you are using `poll`/`poll_one`/`run_one` or otherwise manually driving the `io_context` event loop you may need to adjust usage to make sure you are correctly recognizing the "done with work" and "not done but idling / `io_context::work`" cases. ### Is there a way to check the validity of a `connection_hdl`? diff --git a/examples/broadcast_server/broadcast_server.cpp b/examples/broadcast_server/broadcast_server.cpp index 35976d35a..efdd4edd4 100644 --- a/examples/broadcast_server/broadcast_server.cpp +++ b/examples/broadcast_server/broadcast_server.cpp @@ -75,7 +75,7 @@ class broadcast_server { return; } - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop //try { m_server.run(); //} catch (const std::exception & e) { diff --git a/examples/debug_client/debug_client.cpp b/examples/debug_client/debug_client.cpp index 457c24934..81c595b99 100644 --- a/examples/debug_client/debug_client.cpp +++ b/examples/debug_client/debug_client.cpp @@ -82,7 +82,7 @@ class perftest { m_endpoint.connect(con); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop m_start = std::chrono::high_resolution_clock::now(); m_endpoint.run(); } diff --git a/examples/debug_server/debug_server.cpp b/examples/debug_server/debug_server.cpp index 8d1ff0ee6..3748800b5 100644 --- a/examples/debug_server/debug_server.cpp +++ b/examples/debug_server/debug_server.cpp @@ -162,7 +162,7 @@ int main() { // Start the server accept loop echo_server.start_accept(); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop echo_server.run(); } catch (websocketpp::exception const & e) { std::cout << e.what() << std::endl; diff --git a/examples/echo_client/echo_client.cpp b/examples/echo_client/echo_client.cpp index 59af6614f..88171d9fc 100644 --- a/examples/echo_client/echo_client.cpp +++ b/examples/echo_client/echo_client.cpp @@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { // exchanged until the event loop starts running in the next line. c.connect(con); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop // this will cause a single connection to be made to the server. c.run() // will exit when this connection is closed. c.run(); diff --git a/examples/echo_server/echo_server.cpp b/examples/echo_server/echo_server.cpp index aca3f6a9a..2eb3634d8 100644 --- a/examples/echo_server/echo_server.cpp +++ b/examples/echo_server/echo_server.cpp @@ -62,7 +62,7 @@ int main() { // Start the server accept loop echo_server.start_accept(&on_end_accept); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop echo_server.run(); } catch (websocketpp::exception const & e) { std::cout << e.what() << std::endl; diff --git a/examples/echo_server_both/echo_server_both.cpp b/examples/echo_server_both/echo_server_both.cpp index 06b50514a..f4f1bd2e3 100644 --- a/examples/echo_server_both/echo_server_both.cpp +++ b/examples/echo_server_both/echo_server_both.cpp @@ -65,14 +65,14 @@ context_ptr on_tls_init(websocketpp::connection_hdl hdl) { } int main() { - // set up an external io_service to run both endpoints on. This is not + // set up an external io_context to run both endpoints on. This is not // strictly necessary, but simplifies thread management a bit. - boost::asio::io_service ios; + boost::asio::io_context ctx; // set up plain endpoint server_plain endpoint_plain; - // initialize asio with our external io_service rather than an internal one - endpoint_plain.init_asio(&ios); + // initialize asio with our external io_context rather than an internal one + endpoint_plain.init_asio(&ctx); endpoint_plain.set_message_handler( bind(&on_message,&endpoint_plain,::_1,::_2)); endpoint_plain.listen(80); @@ -80,7 +80,7 @@ int main() { // set up tls endpoint server_tls endpoint_tls; - endpoint_tls.init_asio(&ios); + endpoint_tls.init_asio(&ctx); endpoint_tls.set_message_handler( bind(&on_message,&endpoint_tls,::_1,::_2)); // TLS endpoint has an extra handler for the tls init @@ -89,6 +89,6 @@ int main() { endpoint_tls.listen(443); endpoint_tls.start_accept(&on_end_accept); - // Start the ASIO io_service run loop running both endpoints - ios.run(); + // Start the ASIO io_context run loop running both endpoints + ctx.run(); } diff --git a/examples/echo_server_tls/echo_server_tls.cpp b/examples/echo_server_tls/echo_server_tls.cpp index ef14a4a22..e05680505 100644 --- a/examples/echo_server_tls/echo_server_tls.cpp +++ b/examples/echo_server_tls/echo_server_tls.cpp @@ -155,7 +155,7 @@ int main() { // Start the server accept loop echo_server.start_accept(&on_end_accept); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop echo_server.run(); } diff --git a/examples/external_io_service/CMakeLists.txt b/examples/external_io_context/CMakeLists.txt similarity index 87% rename from examples/external_io_service/CMakeLists.txt rename to examples/external_io_context/CMakeLists.txt index 5223da1be..a0e89ec96 100644 --- a/examples/external_io_service/CMakeLists.txt +++ b/examples/external_io_context/CMakeLists.txt @@ -2,7 +2,7 @@ file (GLOB SOURCE_FILES *.cpp) file (GLOB HEADER_FILES *.hpp) -init_target (external_io_service) +init_target (external_io_context) build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES}) diff --git a/examples/external_io_service/SConscript b/examples/external_io_context/SConscript similarity index 72% rename from examples/external_io_service/SConscript rename to examples/external_io_context/SConscript index 0abf3e175..c6cd9740d 100644 --- a/examples/external_io_service/SConscript +++ b/examples/external_io_context/SConscript @@ -15,9 +15,9 @@ prgs = [] # if a C++11 environment is available build using that, otherwise use boost if 'WSPP_CPP11_ENABLED' in env_cpp11: ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] - prgs += env_cpp11.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) + prgs += env_cpp11.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) else: ALL_LIBS = boostlibs(['system'],env) + [platform_libs] + [polyfill_libs] - prgs += env.Program('external_io_service', ["external_io_service.cpp"], LIBS = ALL_LIBS) + prgs += env.Program('external_io_context', ["external_io_context.cpp"], LIBS = ALL_LIBS) Return('prgs') diff --git a/examples/external_io_service/external_io_service.cpp b/examples/external_io_context/external_io_context.cpp similarity index 93% rename from examples/external_io_service/external_io_service.cpp rename to examples/external_io_context/external_io_context.cpp index 6aa23985e..c671e454f 100644 --- a/examples/external_io_service/external_io_service.cpp +++ b/examples/external_io_context/external_io_context.cpp @@ -66,10 +66,10 @@ void on_end_accept(error_code lib_ec, error_code trans_ec) { } int main() { - asio::io_service service; + asio::io_context context; // Add a TCP echo server on port 9003 - tcp_echo_server custom_http_server(service, 9003); + tcp_echo_server custom_http_server(context, 9003); // Add a WebSocket echo server on port 9002 ws_echo_server ws_server; @@ -77,8 +77,8 @@ int main() { ws_server.clear_access_channels(websocketpp::log::alevel::frame_payload); // The only difference in this code between an internal and external - // io_service is the different constructor to init_asio - ws_server.init_asio(&service); + // io_context is the different constructor to init_asio + ws_server.init_asio(&context); // Register our message handler ws_server.set_message_handler(bind(&on_message,&ws_server,::_1,::_2)); @@ -87,6 +87,6 @@ int main() { // TODO: add a timer? - // Start the Asio io_service run loop for all - service.run(); + // Start the Asio io_context run loop for all + context.run(); } \ No newline at end of file diff --git a/examples/external_io_service/tcp_echo_server.hpp b/examples/external_io_context/tcp_echo_server.hpp similarity index 92% rename from examples/external_io_service/tcp_echo_server.hpp rename to examples/external_io_context/tcp_echo_server.hpp index ef4ce1855..2e14703f5 100644 --- a/examples/external_io_service/tcp_echo_server.hpp +++ b/examples/external_io_context/tcp_echo_server.hpp @@ -44,7 +44,7 @@ namespace asio = websocketpp::lib::asio; struct tcp_echo_session : websocketpp::lib::enable_shared_from_this { typedef websocketpp::lib::shared_ptr ptr; - tcp_echo_session(asio::io_service & service) : m_socket(service) {} + tcp_echo_session(asio::io_context & context) : m_socket(context) {} void start() { m_socket.async_read_some(asio::buffer(m_buffer, sizeof(m_buffer)), @@ -72,15 +72,15 @@ struct tcp_echo_session : websocketpp::lib::enable_shared_from_thisstart_accept(); } void start_accept() { - tcp_echo_session::ptr new_session(new tcp_echo_session(m_service)); + tcp_echo_session::ptr new_session(new tcp_echo_session(m_context)); m_acceptor.async_accept(new_session->m_socket, bind(&tcp_echo_server::handle_accept, this, new_session, _1)); } @@ -92,6 +92,6 @@ struct tcp_echo_server { start_accept(); } - asio::io_service & m_service; + asio::io_context & m_context; asio::ip::tcp::acceptor m_acceptor; }; diff --git a/examples/print_client/print_client.cpp b/examples/print_client/print_client.cpp index 7ba6e5fc9..20a2bd3e8 100644 --- a/examples/print_client/print_client.cpp +++ b/examples/print_client/print_client.cpp @@ -68,7 +68,7 @@ int main(int argc, char* argv[]) { // exchanged until the event loop starts running in the next line. c.connect(con); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop // this will cause a single connection to be made to the server. c.run() // will exit when this connection is closed. c.run(); diff --git a/examples/print_client_tls/print_client_tls.cpp b/examples/print_client_tls/print_client_tls.cpp index 469d9c61e..43164eaf7 100644 --- a/examples/print_client_tls/print_client_tls.cpp +++ b/examples/print_client_tls/print_client_tls.cpp @@ -239,7 +239,7 @@ int main(int argc, char* argv[]) { c.get_alog().write(websocketpp::log::alevel::app, "Connecting to " + uri); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop // this will cause a single connection to be made to the server. c.run() // will exit when this connection is closed. c.run(); diff --git a/examples/scratch_server/scratch_server.cpp b/examples/scratch_server/scratch_server.cpp index 901ae8e5d..dab20b90d 100644 --- a/examples/scratch_server/scratch_server.cpp +++ b/examples/scratch_server/scratch_server.cpp @@ -94,7 +94,7 @@ int main(int argc, char * argv[]) { // Start the server accept loop echo_server.start_accept(); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop echo_server.run(); } catch (websocketpp::exception const & e) { std::cout << e.what() << std::endl; diff --git a/examples/sip_client/sip_client.cpp b/examples/sip_client/sip_client.cpp index 66fa85784..c9f33e771 100644 --- a/examples/sip_client/sip_client.cpp +++ b/examples/sip_client/sip_client.cpp @@ -69,7 +69,7 @@ int main(int argc, char* argv[]) { sip_client.connect(con); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop sip_client.run(); while(!received) { diff --git a/examples/telemetry_client/telemetry_client.cpp b/examples/telemetry_client/telemetry_client.cpp index f0f7fae72..12390b821 100644 --- a/examples/telemetry_client/telemetry_client.cpp +++ b/examples/telemetry_client/telemetry_client.cpp @@ -62,10 +62,10 @@ class telemetry_client { m_hdl = con->get_handle(); // Queue the connection. No DNS queries or network connections will be - // made until the io_service event loop is run. + // made until the io_context event loop is run. m_client.connect(con); - // Create a thread to run the ASIO io_service event loop + // Create a thread to run the ASIO io_context event loop websocketpp::lib::thread asio_thread(&client::run, &m_client); // Create a thread to run the telemetry loop diff --git a/examples/telemetry_server/telemetry_server.cpp b/examples/telemetry_server/telemetry_server.cpp index 22c155edf..9c576421a 100644 --- a/examples/telemetry_server/telemetry_server.cpp +++ b/examples/telemetry_server/telemetry_server.cpp @@ -69,7 +69,7 @@ class telemetry_server { // Set the initial timer to start telemetry set_timer(); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop try { m_endpoint.run(); } catch (websocketpp::exception const & e) { diff --git a/examples/testee_client/testee_client.cpp b/examples/testee_client/testee_client.cpp index b66e63353..d53997b9d 100644 --- a/examples/testee_client/testee_client.cpp +++ b/examples/testee_client/testee_client.cpp @@ -117,13 +117,13 @@ int main(int argc, char* argv[]) { client::connection_ptr con = c.get_connection(uri+"/getCaseCount", ec); c.connect(con); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop c.run(); std::cout << "case count: " << case_count << std::endl; for (int i = 1; i <= case_count; i++) { - c.reset(); + c.restart(); std::stringstream url; diff --git a/examples/testee_server/testee_server.cpp b/examples/testee_server/testee_server.cpp index cf876f7e1..7ff1b050f 100644 --- a/examples/testee_server/testee_server.cpp +++ b/examples/testee_server/testee_server.cpp @@ -131,7 +131,7 @@ int main(int argc, char * argv[]) { // Start the server accept loop testee_server.start_accept(&on_end_accept); - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop if (num_threads == 1) { testee_server.run(); } else { diff --git a/roadmap.md b/roadmap.md index b35c54ad0..c6103322f 100644 --- a/roadmap.md +++ b/roadmap.md @@ -16,7 +16,7 @@ Complete & Tested: - open_handler - close_handler - echo_server & echo_server_tls -- External io_service support +- External io_context support - TLS support - exception/error handling - Timeouts diff --git a/test/endpoint/endpoint.cpp b/test/endpoint/endpoint.cpp index b4c429ebc..0f1440683 100644 --- a/test/endpoint/endpoint.cpp +++ b/test/endpoint/endpoint.cpp @@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE( initialize_server_asio ) { BOOST_AUTO_TEST_CASE( initialize_server_asio_external ) { websocketpp::server s; - boost::asio::io_service ios; - s.init_asio(&ios); + boost::asio::io_context ctx; + s.init_asio(&ctx); } #ifdef _WEBSOCKETPP_MOVE_SEMANTICS_ @@ -141,8 +141,8 @@ BOOST_AUTO_TEST_CASE( listen_after_listen_failure ) { server1.init_asio(); server2.init_asio(); - boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::address::from_string("127.0.0.1"), 12345); - boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::address::from_string("127.0.0.1"), 23456); + boost::asio::ip::tcp::endpoint ep1(boost::asio::ip::make_address("127.0.0.1"), 12345); + boost::asio::ip::tcp::endpoint ep2(boost::asio::ip::make_address("127.0.0.1"), 23456); server1.listen(ep1, ec); BOOST_CHECK(!ec); diff --git a/test/transport/asio/timers.cpp b/test/transport/asio/timers.cpp index aa03d6189..5e8a03412 100644 --- a/test/transport/asio/timers.cpp +++ b/test/transport/asio/timers.cpp @@ -54,9 +54,9 @@ void run_dummy_server(int port) { using boost::asio::ip::tcp; try { - boost::asio::io_service io_service; - tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); - tcp::socket socket(io_service); + boost::asio::io_context io_context; + tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); + tcp::socket socket(io_context); acceptor.accept(socket); for (;;) { @@ -79,8 +79,8 @@ void run_dummy_server(int port) { // Wait for the specified time period then fail the test void run_test_timer(long value) { - boost::asio::io_service ios; - boost::asio::deadline_timer t(ios,boost::posix_time::milliseconds(value)); + boost::asio::io_context ctx; + boost::asio::deadline_timer t(ctx,boost::posix_time::milliseconds(value)); boost::system::error_code ec; t.wait(ec); BOOST_FAIL( "Test timed out" ); diff --git a/test/transport/integration.cpp b/test/transport/integration.cpp index c083cfd01..cb4b7a22d 100644 --- a/test/transport/integration.cpp +++ b/test/transport/integration.cpp @@ -221,9 +221,9 @@ void run_dummy_server(int port) { using boost::asio::ip::tcp; try { - boost::asio::io_service io_service; - tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v6(), port)); - tcp::socket socket(io_service); + boost::asio::io_context io_context; + tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v6(), port)); + tcp::socket socket(io_context); acceptor.accept(socket); for (;;) { @@ -248,13 +248,12 @@ void run_dummy_client(std::string port) { using boost::asio::ip::tcp; try { - boost::asio::io_service io_service; - tcp::resolver resolver(io_service); - tcp::resolver::query query("localhost", port); - tcp::resolver::iterator iterator = resolver.resolve(query); - tcp::socket socket(io_service); + boost::asio::io_context io_context; + tcp::resolver resolver(io_context); + tcp::resolver::results_type results = resolver.resolve("localhost", port); + tcp::socket socket(io_context); - boost::asio::connect(socket, iterator); + boost::asio::connect(socket, results); for (;;) { char data[512]; boost::system::error_code ec; @@ -358,11 +357,11 @@ class test_deadline_timer { public: test_deadline_timer(int seconds) - : m_timer(m_io_service, boost::posix_time::seconds(seconds)) + : m_timer(m_io_context, boost::posix_time::seconds(seconds)) { m_timer.async_wait(bind(&test_deadline_timer::expired, this, ::_1)); - std::size_t (boost::asio::io_service::*run)() = &boost::asio::io_service::run; - m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_service)); + std::size_t (boost::asio::io_context::*run)() = &boost::asio::io_context::run; + m_timer_thread = websocketpp::lib::thread(websocketpp::lib::bind(run, &m_io_context)); } ~test_deadline_timer() { @@ -379,7 +378,7 @@ class test_deadline_timer BOOST_FAIL("Test timed out"); } - boost::asio::io_service m_io_service; + boost::asio::io_context m_io_context; boost::asio::deadline_timer m_timer; websocketpp::lib::thread m_timer_thread; }; @@ -541,7 +540,7 @@ BOOST_AUTO_TEST_CASE( client_runs_out_of_work ) { c.run(); - // This test checks that an io_service with no work ends immediately. + // This test checks that an io_context with no work ends immediately. BOOST_CHECK(true); } diff --git a/tutorials/utility_server/step1.cpp b/tutorials/utility_server/step1.cpp index c0e464382..dae4a2ab9 100644 --- a/tutorials/utility_server/step1.cpp +++ b/tutorials/utility_server/step1.cpp @@ -57,7 +57,7 @@ class utility_server { // Queues a connection accept operation m_endpoint.start_accept(); - // Start the Asio io_service run loop + // Start the Asio io_context run loop m_endpoint.run(); } private: diff --git a/tutorials/utility_server/step2.cpp b/tutorials/utility_server/step2.cpp index a2815bbb9..c4fe486c1 100644 --- a/tutorials/utility_server/step2.cpp +++ b/tutorials/utility_server/step2.cpp @@ -68,7 +68,7 @@ class utility_server { // Queues a connection accept operation m_endpoint.start_accept(); - // Start the Asio io_service run loop + // Start the Asio io_context run loop m_endpoint.run(); } private: diff --git a/tutorials/utility_server/utility_server.md b/tutorials/utility_server/utility_server.md index 1c7ee3fc1..461eed071 100644 --- a/tutorials/utility_server/utility_server.md +++ b/tutorials/utility_server/utility_server.md @@ -56,7 +56,7 @@ m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log: Next, we initialize the transport system underlying the endpoint. This method is specific to the Asio transport not WebSocket++ core. It will not be necessary or present in endpoints that use a non-asio config. -> **Note:** This example uses an internal Asio `io_service` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_service` object or want to build a new program where WebSocket++ handlers share an io_service with other handlers you can pass the `io_service` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?] +> **Note:** This example uses an internal Asio `io_context` that is managed by the endpoint itself. This is a simple arrangement suitable for programs where WebSocket++ is the only code using Asio. If you have an existing program that already manages an `io_context` object or want to build a new program where WebSocket++ handlers share an io_context with other handlers you can pass the `io_context` you want WebSocket++ to register its handlers on to the `init_asio()` method and it will use it instead of generating and managing its own. [TODO: FAQ link instead?] ~~~{.cpp} m_endpoint.init_asio(); @@ -64,7 +64,7 @@ m_endpoint.init_asio(); #### `utility_server::run` method -In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_service event loop. +In addition to the constructor, we also add a run method that sets up the listening socket, begins accepting connections, starts the Asio io_context event loop. ~~~{.cpp} // Listen on port 9002 @@ -73,7 +73,7 @@ m_endpoint.listen(9002); // Queues a connection accept operation m_endpoint.start_accept(); -// Start the Asio io_service run loop +// Start the Asio io_context run loop m_endpoint.run(); ~~~ @@ -123,7 +123,7 @@ public: // Queues a connection accept operation m_endpoint.start_accept(); - // Start the Asio io_service run loop + // Start the Asio io_context run loop m_endpoint.run(); } private: diff --git a/websocketpp/roles/server_endpoint.hpp b/websocketpp/roles/server_endpoint.hpp index 04fee18f9..b69281fdb 100644 --- a/websocketpp/roles/server_endpoint.hpp +++ b/websocketpp/roles/server_endpoint.hpp @@ -137,8 +137,8 @@ class server : public endpoint,config> { /// Starts the server's async connection acceptance loop (exception free) /** * Initiates the server connection acceptance loop. Must be called after - * listen. This method will have no effect until the underlying io_service - * starts running. It may be called after the io_service is already running. + * listen. This method will have no effect until the underlying io_context + * starts running. It may be called after the io_context is already running. * * Refer to documentation for the transport policy you are using for * instructions on how to stop this acceptance loop. diff --git a/websocketpp/transport/asio/base.hpp b/websocketpp/transport/asio/base.hpp index b945fe11f..8d980ad7c 100644 --- a/websocketpp/transport/asio/base.hpp +++ b/websocketpp/transport/asio/base.hpp @@ -40,7 +40,7 @@ namespace websocketpp { namespace transport { /// Transport policy that uses asio /** - * This policy uses a single asio io_service to provide transport + * This policy uses a single asio io_context to provide transport * services to a WebSocket++ endpoint. */ namespace asio { diff --git a/websocketpp/transport/asio/connection.hpp b/websocketpp/transport/asio/connection.hpp index ea18e3e6d..cb901435a 100644 --- a/websocketpp/transport/asio/connection.hpp +++ b/websocketpp/transport/asio/connection.hpp @@ -85,10 +85,10 @@ class connection : public config::socket_type::socket_con_type { typedef typename config::response_type response_type; typedef typename response_type::ptr response_ptr; - /// Type of a pointer to the Asio io_service being used - typedef lib::asio::io_service * io_service_ptr; - /// Type of a pointer to the Asio io_service::strand being used - typedef lib::shared_ptr strand_ptr; + /// Type of a pointer to the Asio io_context being used + typedef lib::asio::io_context * io_context_ptr; + /// Type of a pointer to the Asio io_context::strand being used + typedef lib::shared_ptr strand_ptr; /// Type of a pointer to the Asio timer class typedef lib::shared_ptr timer_ptr; @@ -97,7 +97,7 @@ class connection : public config::socket_type::socket_con_type { // to the public api. friend class endpoint; - // generate and manage our own io_service + // generate and manage our own io_context explicit connection(bool is_server, const lib::shared_ptr & alog, const lib::shared_ptr & elog) : m_is_server(is_server) , m_alog(alog) @@ -319,7 +319,7 @@ class connection : public config::socket_type::socket_con_type { timer_ptr set_timer(long duration, timer_handler callback) { timer_ptr new_timer( new lib::asio::steady_timer( - *m_io_service, + *m_io_context, lib::asio::milliseconds(duration)) ); @@ -399,7 +399,7 @@ class connection : public config::socket_type::socket_con_type { /// Initialize transport for reading /** * init_asio is called once immediately after construction to initialize - * Asio components to the io_service + * Asio components to the io_context * * The transport initialization sequence consists of the following steps: * - Pre-init: the underlying socket is initialized to the point where @@ -457,21 +457,21 @@ class connection : public config::socket_type::socket_con_type { /// Finish constructing the transport /** * init_asio is called once immediately after construction to initialize - * Asio components to the io_service. + * Asio components to the io_context. * - * @param io_service A pointer to the io_service to register with this + * @param io_context A pointer to the io_context to register with this * connection * * @return Status code for the success or failure of the initialization */ - lib::error_code init_asio (io_service_ptr io_service) { - m_io_service = io_service; + lib::error_code init_asio (io_context_ptr io_context) { + m_io_context = io_context; if (config::enable_multithreading) { - m_strand.reset(new lib::asio::io_service::strand(*io_service)); + m_strand.reset(new lib::asio::io_context::strand(*io_context)); } - lib::error_code ec = socket_con_type::init_asio(io_service, m_strand, + lib::error_code ec = socket_con_type::init_asio(io_context, m_strand, m_is_server); return ec; @@ -579,7 +579,7 @@ class connection : public config::socket_type::socket_con_type { lib::error_code const & ec) { if (ec == transport::error::operation_aborted || - (post_timer && lib::asio::is_neg(post_timer->expires_from_now()))) + (post_timer && lib::asio::is_neg(post_timer->expiry() - timer_ptr::element_type::clock_type::now()))) { m_alog->write(log::alevel::devel,"post_init cancelled"); return; @@ -685,7 +685,7 @@ class connection : public config::socket_type::socket_con_type { // Whatever aborted it will be issuing the callback so we are safe to // return if (ec == lib::asio::error::operation_aborted || - lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) + lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) { m_elog->write(log::elevel::devel,"write operation aborted"); return; @@ -756,7 +756,7 @@ class connection : public config::socket_type::socket_con_type { // Whatever aborted it will be issuing the callback so we are safe to // return if (ec == lib::asio::error::operation_aborted || - lib::asio::is_neg(m_proxy_data->timer->expires_from_now())) + lib::asio::is_neg(m_proxy_data->timer->expiry() - timer_ptr::element_type::clock_type::now())) { m_elog->write(log::elevel::devel,"read operation aborted"); return; @@ -1030,18 +1030,18 @@ class connection : public config::socket_type::socket_con_type { */ lib::error_code interrupt(interrupt_handler handler) { if (config::enable_multithreading) { - m_io_service->post(m_strand->wrap(handler)); + lib::asio::post((*m_io_context), m_strand->wrap(handler)); } else { - m_io_service->post(handler); + lib::asio::post((*m_io_context), handler); } return lib::error_code(); } lib::error_code dispatch(dispatch_handler handler) { if (config::enable_multithreading) { - m_io_service->post(m_strand->wrap(handler)); + lib::asio::post((*m_io_context), m_strand->wrap(handler)); } else { - m_io_service->post(handler); + lib::asio::post((*m_io_context), handler); } return lib::error_code(); } @@ -1113,7 +1113,7 @@ class connection : public config::socket_type::socket_con_type { callback, lib::asio::error_code const & ec) { if (ec == lib::asio::error::operation_aborted || - lib::asio::is_neg(shutdown_timer->expires_from_now())) + lib::asio::is_neg(shutdown_timer->expiry() - timer_ptr::element_type::clock_type::now())) { m_alog->write(log::alevel::devel,"async_shutdown cancelled"); return; @@ -1190,7 +1190,7 @@ class connection : public config::socket_type::socket_con_type { lib::shared_ptr m_proxy_data; // transport resources - io_service_ptr m_io_service; + io_context_ptr m_io_context; strand_ptr m_strand; connection_hdl m_connection_hdl; diff --git a/websocketpp/transport/asio/endpoint.hpp b/websocketpp/transport/asio/endpoint.hpp index 125b87642..08d6d1e3b 100644 --- a/websocketpp/transport/asio/endpoint.hpp +++ b/websocketpp/transport/asio/endpoint.hpp @@ -77,25 +77,25 @@ class endpoint : public config::socket_type { /// associated with this endpoint transport component typedef typename transport_con_type::ptr transport_con_ptr; - /// Type of a pointer to the ASIO io_service being used - typedef lib::asio::io_service * io_service_ptr; + /// Type of a pointer to the ASIO io_context being used + typedef lib::asio::io_context * io_context_ptr; /// Type of a shared pointer to the acceptor being used typedef lib::shared_ptr acceptor_ptr; /// Type of a shared pointer to the resolver being used typedef lib::shared_ptr resolver_ptr; /// Type of timer handle typedef lib::shared_ptr timer_ptr; - /// Type of a shared pointer to an io_service work object - typedef lib::shared_ptr work_ptr; + /// Type of a shared pointer to an asio executor_work_guard object + typedef lib::shared_ptr> work_guard_ptr; /// Type of socket pre-bind handler typedef lib::function tcp_pre_bind_handler; - // generate and manage our own io_service + // generate and manage our own io_context explicit endpoint() - : m_io_service(NULL) - , m_external_io_service(false) - , m_listen_backlog(lib::asio::socket_base::max_connections) + : m_io_context(NULL) + , m_external_io_context(false) + , m_listen_backlog(lib::asio::socket_base::max_listen_connections) , m_reuse_addr(false) , m_state(UNINITIALIZED) { @@ -103,14 +103,14 @@ class endpoint : public config::socket_type { } ~endpoint() { - // clean up our io_service if we were initialized with an internal one. + // clean up our io_context if we were initialized with an internal one. // Explicitly destroy local objects m_acceptor.reset(); m_resolver.reset(); - m_work.reset(); - if (m_state != UNINITIALIZED && !m_external_io_service) { - delete m_io_service; + m_work_guard.reset(); + if (m_state != UNINITIALIZED && !m_external_io_context) { + delete m_io_context; } } @@ -132,34 +132,34 @@ class endpoint : public config::socket_type { : config::socket_type(std::move(src)) , m_tcp_pre_init_handler(src.m_tcp_pre_init_handler) , m_tcp_post_init_handler(src.m_tcp_post_init_handler) - , m_io_service(src.m_io_service) - , m_external_io_service(src.m_external_io_service) + , m_io_context(src.m_io_context) + , m_external_io_context(src.m_external_io_context) , m_acceptor(src.m_acceptor) - , m_listen_backlog(lib::asio::socket_base::max_connections) + , m_listen_backlog(lib::asio::socket_base::max_listen_connections) , m_reuse_addr(src.m_reuse_addr) , m_elog(src.m_elog) , m_alog(src.m_alog) , m_state(src.m_state) { - src.m_io_service = NULL; - src.m_external_io_service = false; + src.m_io_context = NULL; + src.m_external_io_context = false; src.m_acceptor = NULL; src.m_state = UNINITIALIZED; } /*endpoint & operator= (const endpoint && rhs) { if (this != &rhs) { - m_io_service = rhs.m_io_service; - m_external_io_service = rhs.m_external_io_service; + m_io_context = rhs.m_io_context; + m_external_io_context = rhs.m_external_io_context; m_acceptor = rhs.m_acceptor; m_listen_backlog = rhs.m_listen_backlog; m_reuse_addr = rhs.m_reuse_addr; m_state = rhs.m_state; - rhs.m_io_service = NULL; - rhs.m_external_io_service = false; + rhs.m_io_context = NULL; + rhs.m_external_io_context = false; rhs.m_acceptor = NULL; - rhs.m_listen_backlog = lib::asio::socket_base::max_connections; + rhs.m_listen_backlog = lib::asio::socket_base::max_listen_connections; rhs.m_state = UNINITIALIZED; // TODO: this needs to be updated @@ -173,16 +173,16 @@ class endpoint : public config::socket_type { return socket_type::is_secure(); } - /// initialize asio transport with external io_service (exception free) + /// initialize asio transport with external io_context (exception free) /** * Initialize the ASIO transport policy for this endpoint using the provided - * io_service object. asio_init must be called exactly once on any endpoint + * io_context object. asio_init must be called exactly once on any endpoint * that uses transport::asio before it can be used. * - * @param ptr A pointer to the io_service to use for asio events + * @param ptr A pointer to the io_context to use for asio events * @param ec Set to indicate what error occurred, if any. */ - void init_asio(io_service_ptr ptr, lib::error_code & ec) { + void init_asio(io_context_ptr ptr, lib::error_code & ec) { if (m_state != UNINITIALIZED) { m_elog->write(log::elevel::library, "asio::init_asio called from the wrong state"); @@ -193,36 +193,36 @@ class endpoint : public config::socket_type { m_alog->write(log::alevel::devel,"asio::init_asio"); - m_io_service = ptr; - m_external_io_service = true; - m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service)); + m_io_context = ptr; + m_external_io_context = true; + m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_context)); m_state = READY; ec = lib::error_code(); } #ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ - /// initialize asio transport with external io_service + /// initialize asio transport with external io_context /** * Initialize the ASIO transport policy for this endpoint using the provided - * io_service object. asio_init must be called exactly once on any endpoint + * io_context object. asio_init must be called exactly once on any endpoint * that uses transport::asio before it can be used. * - * @param ptr A pointer to the io_service to use for asio events + * @param ptr A pointer to the io_context to use for asio events */ - void init_asio(io_service_ptr ptr) { + void init_asio(io_context_ptr ptr) { lib::error_code ec; init_asio(ptr,ec); if (ec) { throw exception(ec); } } #endif // _WEBSOCKETPP_NO_EXCEPTIONS_ - /// Initialize asio transport with internal io_service (exception free) + /// Initialize asio transport with internal io_context (exception free) /** * This method of initialization will allocate and use an internally managed - * io_service. + * io_context. * - * @see init_asio(io_service_ptr ptr) + * @see init_asio(io_context_ptr ptr) * * @param ec Set to indicate what error occurred, if any. */ @@ -232,22 +232,22 @@ class endpoint : public config::socket_type { // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. #ifdef _WEBSOCKETPP_CPP11_MEMORY_ - lib::unique_ptr service(new lib::asio::io_service()); + lib::unique_ptr context(new lib::asio::io_context()); #else - lib::auto_ptr service(new lib::asio::io_service()); + lib::auto_ptr context(new lib::asio::io_context()); #endif - init_asio(service.get(), ec); - if( !ec ) service.release(); // Call was successful, transfer ownership - m_external_io_service = false; + init_asio(context.get(), ec); + if( !ec ) context.release(); // Call was successful, transfer ownership + m_external_io_context = false; } #ifndef _WEBSOCKETPP_NO_EXCEPTIONS_ - /// Initialize asio transport with internal io_service + /// Initialize asio transport with internal io_context /** * This method of initialization will allocate and use an internally managed - * io_service. + * io_context. * - * @see init_asio(io_service_ptr ptr) + * @see init_asio(io_context_ptr ptr) */ void init_asio() { // Use a smart pointer until the call is successful and ownership has @@ -255,14 +255,14 @@ class endpoint : public config::socket_type { // TODO: remove the use of auto_ptr when C++98/03 support is no longer // necessary. #ifdef _WEBSOCKETPP_CPP11_MEMORY_ - lib::unique_ptr service(new lib::asio::io_service()); + lib::unique_ptr context(new lib::asio::io_context()); #else - lib::auto_ptr service(new lib::asio::io_service()); + lib::auto_ptr context(new lib::asio::io_context()); #endif - init_asio( service.get() ); + init_asio( context.get() ); // If control got this far without an exception, then ownership has successfully been taken - service.release(); - m_external_io_service = false; + context.release(); + m_external_io_context = false; } #endif // _WEBSOCKETPP_NO_EXCEPTIONS_ @@ -334,7 +334,7 @@ class endpoint : public config::socket_type { * * New values affect future calls to listen only. * - * The default value is specified as *::asio::socket_base::max_connections + * The default value is specified as *::asio::socket_base::max_listen_connections * which uses the operating system defined maximum queue length. Your OS * may restrict or silently lower this value. A value of zero may cause * all connections to be rejected. @@ -368,19 +368,19 @@ class endpoint : public config::socket_type { m_reuse_addr = value; } - /// Retrieve a reference to the endpoint's io_service + /// Retrieve a reference to the endpoint's io_context /** - * The io_service may be an internal or external one. This may be used to - * call methods of the io_service that are not explicitly wrapped by the + * The io_context may be an internal or external one. This may be used to + * call methods of the io_context that are not explicitly wrapped by the * endpoint. * * This method is only valid after the endpoint has been initialized with * `init_asio`. No error will be returned if it isn't. * - * @return A reference to the endpoint's io_service + * @return A reference to the endpoint's io_context */ - lib::asio::io_service & get_io_service() { - return *m_io_service; + lib::asio::io_context & get_io_context() { + return *m_io_context; } /// Get local TCP endpoint @@ -495,13 +495,12 @@ class endpoint : public config::socket_type { /** * Bind the internal acceptor using the given host and service. More details * about what host and service can be are available in the Asio - * documentation for ip::basic_resolver_query::basic_resolver_query's - * constructors. + * documentation for ip::basic_resolver::resolve function. * * The endpoint must have been initialized by calling init_asio before * listening. * - * Once listening the underlying io_service will be kept open indefinitely. + * Once listening the underlying io_context will be kept open indefinitely. * Calling endpoint::stop_listening will stop the endpoint from accepting * new connections. See the documentation for stop listening for more details * about shutting down Asio Transport based endpoints. @@ -518,17 +517,15 @@ class endpoint : public config::socket_type { lib::error_code & ec) { using lib::asio::ip::tcp; - tcp::resolver r(*m_io_service); - tcp::resolver::query query(host, service); - tcp::resolver::iterator endpoint_iterator = r.resolve(query); - tcp::resolver::iterator end; - if (endpoint_iterator == end) { + tcp::resolver r(*m_io_context); + tcp::resolver::results_type results = r.resolve(host, service); + if (results.empty()) { m_elog->write(log::elevel::library, "asio::listen could not resolve the supplied host or service"); ec = make_error_code(error::invalid_host_service); return; } - listen(*endpoint_iterator,ec); + listen(*(results.begin()),ec); } /// Stop listening (exception free) @@ -615,13 +612,12 @@ class endpoint : public config::socket_type { /** * Bind the internal acceptor using the given host and service. More * details about what host and service can be are available in the Asio - * documentation for ip::basic_resolver_query::basic_resolver_query's - * constructors. + * documentation for ip::basic_resolver::resolve function. * * The endpoint must have been initialized by calling init_asio before * listening. * - * Once listening the underlying io_service will be kept open indefinitely. + * Once listening the underlying io_context will be kept open indefinitely. * Calling endpoint::stop_listening will stop the endpoint from accepting * new connections. See the documentation for stop listening for more * details about shutting down Asio Transport based endpoints. @@ -663,42 +659,42 @@ class endpoint : public config::socket_type { return (m_state == LISTENING); } - /// wraps the run method of the internal io_service object + /// wraps the run method of the internal io_context object std::size_t run() { - return m_io_service->run(); + return m_io_context->run(); } - /// wraps the run_one method of the internal io_service object + /// wraps the run_one method of the internal io_context object /** * @since 0.3.0-alpha4 */ std::size_t run_one() { - return m_io_service->run_one(); + return m_io_context->run_one(); } - /// wraps the stop method of the internal io_service object + /// wraps the stop method of the internal io_context object void stop() { - m_io_service->stop(); + m_io_context->stop(); } - /// wraps the poll method of the internal io_service object + /// wraps the poll method of the internal io_context object std::size_t poll() { - return m_io_service->poll(); + return m_io_context->poll(); } - /// wraps the poll_one method of the internal io_service object + /// wraps the poll_one method of the internal io_context object std::size_t poll_one() { - return m_io_service->poll_one(); + return m_io_context->poll_one(); } - /// wraps the reset method of the internal io_service object - void reset() { - m_io_service->reset(); + /// wraps the restart method of the internal io_context object + void restart() { + m_io_context->restart(); } - /// wraps the stopped method of the internal io_service object + /// wraps the stopped method of the internal io_context object bool stopped() const { - return m_io_service->stopped(); + return m_io_context->stopped(); } /// Marks the endpoint as perpetual, stopping it from exiting when empty @@ -714,7 +710,7 @@ class endpoint : public config::socket_type { * @since 0.3.0 */ void start_perpetual() { - m_work.reset(new lib::asio::io_service::work(*m_io_service)); + m_work_guard = lib::make_shared(lib::asio::make_work_guard(*m_io_context)); } /// Clears the endpoint's perpetual flag, allowing it to exit when empty @@ -726,7 +722,7 @@ class endpoint : public config::socket_type { * @since 0.3.0 */ void stop_perpetual() { - m_work.reset(); + m_work_guard.reset(); } /// Call back a function after a period of time. @@ -743,7 +739,7 @@ class endpoint : public config::socket_type { */ timer_ptr set_timer(long duration, timer_handler callback) { timer_ptr new_timer = lib::make_shared( - *m_io_service, + *m_io_context, lib::asio::milliseconds(duration) ); @@ -880,7 +876,7 @@ class endpoint : public config::socket_type { // Create a resolver if (!m_resolver) { - m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service)); + m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_context)); } tcon->set_uri(u); @@ -912,8 +908,6 @@ class endpoint : public config::socket_type { port = pu->get_port_str(); } - tcp::resolver::query query(host,port); - if (m_alog->static_test(log::alevel::devel)) { m_alog->write(log::alevel::devel, "starting async DNS resolve for "+host+":"+port); @@ -934,7 +928,7 @@ class endpoint : public config::socket_type { if (config::enable_multithreading) { m_resolver->async_resolve( - query, + host, port, tcon->get_strand()->wrap(lib::bind( &type::handle_resolve, this, @@ -947,7 +941,7 @@ class endpoint : public config::socket_type { ); } else { m_resolver->async_resolve( - query, + host, port, lib::bind( &type::handle_resolve, this, @@ -995,10 +989,10 @@ class endpoint : public config::socket_type { void handle_resolve(transport_con_ptr tcon, timer_ptr dns_timer, connect_handler callback, lib::asio::error_code const & ec, - lib::asio::ip::tcp::resolver::iterator iterator) + lib::asio::ip::tcp::resolver::results_type results) { if (ec == lib::asio::error::operation_aborted || - lib::asio::is_neg(dns_timer->expires_from_now())) + lib::asio::is_neg(dns_timer->expiry() - timer_ptr::element_type::clock_type::now())) { m_alog->write(log::alevel::devel,"async_resolve cancelled"); return; @@ -1016,8 +1010,8 @@ class endpoint : public config::socket_type { std::stringstream s; s << "Async DNS resolve successful. Results: "; - lib::asio::ip::tcp::resolver::iterator it, end; - for (it = iterator; it != end; ++it) { + lib::asio::ip::tcp::resolver::results_type::iterator it; + for (it = results.begin(); it != results.end(); ++it) { s << (*it).endpoint() << " "; } @@ -1043,7 +1037,7 @@ class endpoint : public config::socket_type { if (config::enable_multithreading) { lib::asio::async_connect( tcon->get_raw_socket(), - iterator, + results, tcon->get_strand()->wrap(lib::bind( &type::handle_connect, this, @@ -1056,7 +1050,7 @@ class endpoint : public config::socket_type { } else { lib::asio::async_connect( tcon->get_raw_socket(), - iterator, + results, lib::bind( &type::handle_connect, this, @@ -1106,7 +1100,7 @@ class endpoint : public config::socket_type { connect_handler callback, lib::asio::error_code const & ec) { if (ec == lib::asio::error::operation_aborted || - lib::asio::is_neg(con_timer->expires_from_now())) + lib::asio::is_neg(con_timer->expiry() - timer_ptr::element_type::clock_type::now())) { m_alog->write(log::alevel::devel,"async_connect cancelled"); return; @@ -1148,7 +1142,7 @@ class endpoint : public config::socket_type { lib::error_code ec; - ec = tcon->init_asio(m_io_service); + ec = tcon->init_asio(m_io_context); if (ec) {return ec;} tcon->set_tcp_pre_init_handler(m_tcp_pre_init_handler); @@ -1187,11 +1181,11 @@ class endpoint : public config::socket_type { tcp_init_handler m_tcp_post_init_handler; // Network Resources - io_service_ptr m_io_service; - bool m_external_io_service; + io_context_ptr m_io_context; + bool m_external_io_context; acceptor_ptr m_acceptor; resolver_ptr m_resolver; - work_ptr m_work; + work_guard_ptr m_work_guard; // Network constants int m_listen_backlog; diff --git a/websocketpp/transport/asio/security/none.hpp b/websocketpp/transport/asio/security/none.hpp index c679378ed..3033b7648 100644 --- a/websocketpp/transport/asio/security/none.hpp +++ b/websocketpp/transport/asio/security/none.hpp @@ -62,10 +62,10 @@ class connection : public lib::enable_shared_from_this { /// Type of a shared pointer to this connection socket component typedef lib::shared_ptr ptr; - /// Type of a pointer to the Asio io_service being used - typedef lib::asio::io_service* io_service_ptr; - /// Type of a pointer to the Asio io_service strand being used - typedef lib::shared_ptr strand_ptr; + /// Type of a pointer to the Asio io_context being used + typedef lib::asio::io_context* io_context_ptr; + /// Type of a pointer to the Asio io_context strand being used + typedef lib::shared_ptr strand_ptr; /// Type of the ASIO socket being used typedef lib::asio::ip::tcp::socket socket_type; /// Type of a shared pointer to the socket being used. @@ -156,20 +156,20 @@ class connection : public lib::enable_shared_from_this { /// Perform one time initializations /** * init_asio is called once immediately after construction to initialize - * Asio components to the io_service. At this stage the connection is + * Asio components to the io_context. At this stage the connection is * speculative, the server may not have actually received a new connection. * - * @param service A pointer to the endpoint's io_service + * @param context A pointer to the endpoint's io_context * @param strand A shared pointer to the connection's asio strand * @param is_server Whether or not the endpoint is a server or not. */ - lib::error_code init_asio (io_service_ptr service, strand_ptr, bool) + lib::error_code init_asio (io_context_ptr context, strand_ptr, bool) { if (m_state != UNINITIALIZED) { return socket::make_error_code(socket::error::invalid_state); } - m_socket.reset(new lib::asio::ip::tcp::socket(*service)); + m_socket.reset(new lib::asio::ip::tcp::socket(*context)); m_state = READY; diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp index 25b0d29d0..d65c48cc9 100644 --- a/websocketpp/transport/asio/security/tls.hpp +++ b/websocketpp/transport/asio/security/tls.hpp @@ -71,10 +71,10 @@ class connection : public lib::enable_shared_from_this { typedef lib::asio::ssl::stream socket_type; /// Type of a shared pointer to the ASIO socket being used typedef lib::shared_ptr socket_ptr; - /// Type of a pointer to the ASIO io_service being used - typedef lib::asio::io_service * io_service_ptr; - /// Type of a pointer to the ASIO io_service strand being used - typedef lib::shared_ptr strand_ptr; + /// Type of a pointer to the ASIO io_context being used + typedef lib::asio::io_context * io_context_ptr; + /// Type of a pointer to the ASIO io_context strand being used + typedef lib::shared_ptr strand_ptr; /// Type of a shared pointer to the ASIO TLS context being used typedef lib::shared_ptr context_ptr; @@ -176,13 +176,13 @@ class connection : public lib::enable_shared_from_this { /// Perform one time initializations /** * init_asio is called once immediately after construction to initialize - * Asio components to the io_service + * Asio components to the io_context * - * @param service A pointer to the endpoint's io_service + * @param context A pointer to the endpoint's io_context * @param strand A pointer to the connection's strand * @param is_server Whether or not the endpoint is a server or not. */ - lib::error_code init_asio (io_service_ptr service, strand_ptr strand, + lib::error_code init_asio (io_context_ptr context, strand_ptr strand, bool is_server) { if (!m_tls_init_handler) { @@ -193,9 +193,9 @@ class connection : public lib::enable_shared_from_this { if (!m_context) { return socket::make_error_code(socket::error::invalid_tls_context); } - m_socket.reset(new socket_type(*service, *m_context)); + m_socket.reset(new socket_type(*context, *m_context)); - m_io_service = service; + m_io_context = context; m_strand = strand; m_is_server = is_server; @@ -391,7 +391,7 @@ class connection : public lib::enable_shared_from_this { } } - io_service_ptr m_io_service; + io_context_ptr m_io_context; strand_ptr m_strand; context_ptr m_context; socket_ptr m_socket; diff --git a/websocketpp/transport/debug/endpoint.hpp b/websocketpp/transport/debug/endpoint.hpp index adc89b382..360644165 100644 --- a/websocketpp/transport/debug/endpoint.hpp +++ b/websocketpp/transport/debug/endpoint.hpp @@ -60,7 +60,7 @@ class endpoint { /// associated connection transport component typedef typename transport_con_type::ptr transport_con_ptr; - // generate and manage our own io_service + // generate and manage our own io_context explicit endpoint() { //std::cout << "transport::iostream::endpoint constructor" << std::endl; diff --git a/websocketpp/transport/iostream/endpoint.hpp b/websocketpp/transport/iostream/endpoint.hpp index 14cba7255..257472db8 100644 --- a/websocketpp/transport/iostream/endpoint.hpp +++ b/websocketpp/transport/iostream/endpoint.hpp @@ -64,7 +64,7 @@ class endpoint { /// associated connection transport component typedef typename transport_con_type::ptr transport_con_ptr; - // generate and manage our own io_service + // generate and manage our own io_context explicit endpoint() : m_output_stream(NULL), m_is_secure(false) { //std::cout << "transport::iostream::endpoint constructor" << std::endl; diff --git a/websocketpp/transport/stub/endpoint.hpp b/websocketpp/transport/stub/endpoint.hpp index eb6570a4c..e0d5f2d3a 100644 --- a/websocketpp/transport/stub/endpoint.hpp +++ b/websocketpp/transport/stub/endpoint.hpp @@ -60,7 +60,7 @@ class endpoint { /// associated connection transport component typedef typename transport_con_type::ptr transport_con_ptr; - // generate and manage our own io_service + // generate and manage our own io_context explicit endpoint() { //std::cout << "transport::iostream::endpoint constructor" << std::endl;