diff --git a/rmf_fleet_adapter/CMakeLists.txt b/rmf_fleet_adapter/CMakeLists.txt index 0588eeac5..0f5615d9d 100644 --- a/rmf_fleet_adapter/CMakeLists.txt +++ b/rmf_fleet_adapter/CMakeLists.txt @@ -107,7 +107,7 @@ target_link_libraries(rmf_fleet_adapter rmf_websocket::rmf_websocket nlohmann_json::nlohmann_json rmf_api_msgs::rmf_api_msgs - nlohmann_json_schema_validator + nlohmann_json_schema_validator::validator ) target_include_directories(rmf_fleet_adapter @@ -118,7 +118,6 @@ target_include_directories(rmf_fleet_adapter PRIVATE ${rmf_api_msgs_INCLUDE_DIRS} ${rmf_websocket_INCLUDE_DIR} - ${nlohmann_json_schema_validator_INCLUDE_DIRS} ) if (BUILD_TESTING) @@ -147,7 +146,6 @@ if (BUILD_TESTING) # private includes of rmf_fleet_adapter $ ${rmf_api_msgs_INCLUDE_DIRS} - ${nlohmann_json_schema_validator_INCLUDE_DIRS} ) target_link_libraries(test_rmf_fleet_adapter PUBLIC @@ -166,7 +164,7 @@ if (BUILD_TESTING) rmf_fleet_adapter rmf_utils::rmf_utils rmf_api_msgs::rmf_api_msgs - nlohmann_json_schema_validator + nlohmann_json_schema_validator::validator ) target_compile_definitions(test_rmf_fleet_adapter diff --git a/rmf_task_ros2/CMakeLists.txt b/rmf_task_ros2/CMakeLists.txt index 9dc2b82ca..8d3ecf973 100644 --- a/rmf_task_ros2/CMakeLists.txt +++ b/rmf_task_ros2/CMakeLists.txt @@ -40,7 +40,7 @@ target_link_libraries(rmf_task_ros2 ${rmf_task_msgs_LIBRARIES} ${rclcpp_LIBRARIES} nlohmann_json::nlohmann_json - nlohmann_json_schema_validator + nlohmann_json_schema_validator::validator ) target_include_directories(rmf_task_ros2 diff --git a/rmf_websocket/CMakeLists.txt b/rmf_websocket/CMakeLists.txt index 168f82003..b3a2948d7 100644 --- a/rmf_websocket/CMakeLists.txt +++ b/rmf_websocket/CMakeLists.txt @@ -1,15 +1,17 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.22) project(rmf_websocket) -# Websocketpp is not compatible with CXX above 17 -set(CMAKE_CXX_STANDARD 17) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") # we dont use add_compile_options with pedantic in message packages # because the Python C extensions dont comply with it set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic") endif() +if(POLICY CMP0167) + cmake_policy(SET CMP0167 NEW) +endif() + include(GNUInstallDirs) find_package(ament_cmake REQUIRED) @@ -19,10 +21,10 @@ find_package(rclcpp REQUIRED) find_package(nlohmann_json REQUIRED) find_package(nlohmann_json_schema_validator_vendor REQUIRED) find_package(nlohmann_json_schema_validator REQUIRED) -find_package(websocketpp REQUIRED) -find_package(Boost COMPONENTS system REQUIRED) +find_package(Boost REQUIRED) find_package(Threads) +add_subdirectory(websocketpp) add_library(rmf_websocket SHARED src/rmf_websocket/client/ClientWebSocketEndpoint.cpp @@ -33,13 +35,13 @@ add_library(rmf_websocket SHARED target_link_libraries(rmf_websocket PUBLIC ${rclcpp_LIBRARIES} - ${websocketpp_LIBRARIES} rmf_utils::rmf_utils nlohmann_json::nlohmann_json - nlohmann_json_schema_validator + nlohmann_json_schema_validator::validator PRIVATE - Boost::system + ${Boost_LIBRARIES} Threads::Threads + websocketpp ) target_include_directories(rmf_websocket @@ -47,16 +49,15 @@ target_include_directories(rmf_websocket $ $ ${rclcpp_INCLUDE_DIRS} - ${WEBSOCKETPP_INCLUDE_DIR} ) add_executable(example_client - examples/client.cpp) + examples/client.cpp +) target_link_libraries(example_client PUBLIC rmf_websocket - ${websocketpp_LIBRARIES} PRIVATE Threads::Threads ) @@ -66,12 +67,11 @@ target_include_directories(example_client $ $ ${rclcpp_INCLUDE_DIRS} - ${WEBSOCKETPP_INCLUDE_DIR} ) ament_export_targets(export_rmf_websocket HAS_LIBRARY_TARGET) -ament_export_dependencies(rmf_traffic rclcpp nlohmann_json websocketpp) +ament_export_dependencies(rmf_traffic rclcpp nlohmann_json) #=============================================================================== install( @@ -112,8 +112,8 @@ if(BUILD_TESTING) target_link_libraries(test_ring_buffer PRIVATE rmf_utils::rmf_utils - Boost::system - ) + ${Boost_LIBRARIES} + ) #integration test find_package(OpenSSL REQUIRED) @@ -122,21 +122,19 @@ if(BUILD_TESTING) TIMEOUT 300) target_link_libraries(test_client PUBLIC - ${websocketpp_LIBRARIES} ${rclcpp_LIBRARIES} rmf_utils::rmf_utils - Boost::system + ${Boost_LIBRARIES} rmf_websocket PRIVATE Threads::Threads OpenSSL::Crypto - ) + ) target_include_directories(test_client PUBLIC $ $ ${rclcpp_INCLUDE_DIRS} - ${WEBSOCKETPP_INCLUDE_DIR} ) @@ -145,10 +143,9 @@ if(BUILD_TESTING) TIMEOUT 300) target_link_libraries(test_client_no_server PUBLIC - ${websocketpp_LIBRARIES} ${rclcpp_LIBRARIES} rmf_utils::rmf_utils - Boost::system + ${Boost_LIBRARIES} rmf_websocket PRIVATE Threads::Threads @@ -159,7 +156,6 @@ if(BUILD_TESTING) $ $ ${rclcpp_INCLUDE_DIRS} - ${WEBSOCKETPP_INCLUDE_DIR} ) ament_add_catch2(test_client_with_update_cb @@ -167,10 +163,9 @@ if(BUILD_TESTING) TIMEOUT 300) target_link_libraries(test_client_with_update_cb PUBLIC - ${websocketpp_LIBRARIES} ${rclcpp_LIBRARIES} rmf_utils::rmf_utils - Boost::system + ${Boost_LIBRARIES} rmf_websocket PRIVATE Threads::Threads @@ -181,7 +176,6 @@ if(BUILD_TESTING) $ $ ${rclcpp_INCLUDE_DIRS} - ${WEBSOCKETPP_INCLUDE_DIR} ) endif() diff --git a/rmf_websocket/src/rmf_websocket/BroadcastClient.cpp b/rmf_websocket/src/rmf_websocket/BroadcastClient.cpp index 7f8d62eb1..6809917ef 100644 --- a/rmf_websocket/src/rmf_websocket/BroadcastClient.cpp +++ b/rmf_websocket/src/rmf_websocket/BroadcastClient.cpp @@ -39,21 +39,23 @@ class BroadcastClient::Implementation const std::shared_ptr& node, ProvideJsonUpdates get_json_updates_cb) : _uri{std::move(uri)}, - _io_service{}, + _io_context{}, _node{std::move(node)}, _queue(1000), _get_json_updates_cb{std::move(get_json_updates_cb)}, _endpoint(_uri, _node, - &_io_service, + &_io_context, std::bind(&BroadcastClient::Implementation::on_connect, this)) { _consumer_thread = std::thread([this]() { - _io_service.run(); + _io_context.run(); }); - _io_service.dispatch([this]() + boost::asio::dispatch( + _io_context, + [this]() { _endpoint.connect(); }); @@ -113,7 +115,9 @@ class BroadcastClient::Implementation RCLCPP_INFO( this->_node->get_logger(), "Attempting queue flush if connected"); - _io_service.dispatch([this]() + boost::asio::dispatch( + _io_context, + [this]() { _flush_queue_if_connected(); }); @@ -134,7 +138,9 @@ class BroadcastClient::Implementation { /// _queue is thread safe. No need to lock. _queue.push(msg); - _io_service.dispatch([this]() + boost::asio::dispatch( + _io_context, + [this]() { _flush_queue_if_connected(); }); @@ -151,7 +157,10 @@ class BroadcastClient::Implementation log("Buffer full dropping oldest message"); } } - _io_service.dispatch([this]() + + boost::asio::dispatch( + _io_context, + [this]() { _flush_queue_if_connected(); }); @@ -168,7 +177,7 @@ class BroadcastClient::Implementation //============================================================================ ~Implementation() { - _io_service.stop(); + _io_context.stop(); _consumer_thread.join(); } @@ -217,7 +226,7 @@ class BroadcastClient::Implementation } // create pimpl std::string _uri; - boost::asio::io_service _io_service; + boost::asio::io_context _io_context; std::shared_ptr _node; RingBuffer _queue; ProvideJsonUpdates _get_json_updates_cb; diff --git a/rmf_websocket/src/rmf_websocket/BroadcastServer.cpp b/rmf_websocket/src/rmf_websocket/BroadcastServer.cpp index e29bf9ede..8f70b984a 100644 --- a/rmf_websocket/src/rmf_websocket/BroadcastServer.cpp +++ b/rmf_websocket/src/rmf_websocket/BroadcastServer.cpp @@ -112,7 +112,7 @@ class BroadcastServer::Implementation "Starting BroadcastServer on port " << endpoint.port()); } - // Start the ASIO io_service run loop + // Start the ASIO io_context run loop _server_thread = std::thread( [data = _data]() { data->echo_server.run(); }); } @@ -128,8 +128,9 @@ class BroadcastServer::Implementation _logger_interface->get_logger(), "Stopping BroadcastServer"); } - _data->echo_server.get_io_service().post( - [data = _data]() + boost::asio::post( + _data->echo_server.get_io_context(), + [data = _data]() { data->echo_server.stop_listening(); data->echo_server.stop(); diff --git a/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp b/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp index 99a823ba4..82bd2972f 100644 --- a/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp +++ b/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.cpp @@ -41,7 +41,7 @@ void ConnectionMetadata::on_fail(WsClient* c, websocketpp::connection_hdl hdl) WsClient::connection_ptr con = c->get_con_from_hdl(hdl); _server = con->get_response_header("Server"); _error_reason = con->get_ec().message(); - c->get_io_service().post(_reconnection_cb); + boost::asio::post(c->get_io_context(), _reconnection_cb); } //============================================================================= @@ -54,7 +54,7 @@ void ConnectionMetadata::on_close(WsClient* c, websocketpp::connection_hdl hdl) << websocketpp::close::status::get_string(con->get_remote_close_code()) << "), close reason: " << con->get_remote_close_reason(); _error_reason = s.str(); - c->get_io_service().post(_reconnection_cb); + boost::asio::post(c->get_io_context(), _reconnection_cb); } //============================================================================= @@ -108,7 +108,7 @@ websocketpp::connection_hdl ConnectionMetadata::get_hdl() const //============================================================================= ClientWebSocketEndpoint::ClientWebSocketEndpoint( std::string const& uri, std::shared_ptr node, - asio::io_service* io_service, + asio::io_context* io_context, ConnectionCallback cb) : _uri(uri), _node(node), _init{false}, _reconnect_enqueued(false), _connection_cb(std::move(cb)) @@ -116,7 +116,7 @@ ClientWebSocketEndpoint::ClientWebSocketEndpoint( _endpoint = std::make_unique(); _endpoint->clear_access_channels(websocketpp::log::alevel::all); _endpoint->clear_error_channels(websocketpp::log::elevel::all); - _endpoint->init_asio(io_service); + _endpoint->init_asio(io_context); _endpoint->start_perpetual(); } @@ -144,11 +144,11 @@ websocketpp::lib::error_code ClientWebSocketEndpoint::connect() "> Reconnecting in 1s\n" "> Host: %s", _uri.c_str()); _endpoint->stop_perpetual(); - auto io_service = &_endpoint->get_io_service(); + auto io_context = &_endpoint->get_io_context(); _endpoint = std::make_unique(); _endpoint->clear_access_channels(websocketpp::log::alevel::all); _endpoint->clear_error_channels(websocketpp::log::elevel::all); - _endpoint->init_asio(io_service); + _endpoint->init_asio(io_context); _endpoint->start_perpetual(); websocketpp::lib::error_code ec; diff --git a/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp b/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp index 55f7105c3..e19d154fe 100644 --- a/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp +++ b/rmf_websocket/src/rmf_websocket/client/ClientWebSocketEndpoint.hpp @@ -101,7 +101,7 @@ class ClientWebSocketEndpoint ClientWebSocketEndpoint( std::string const& uri, std::shared_ptr node, - boost::asio::io_service* io_service, + boost::asio::io_context* io_context, ConnectionCallback cb); /// Delete move constructor diff --git a/rmf_websocket/websocketpp/CMakeLists.txt b/rmf_websocket/websocketpp/CMakeLists.txt new file mode 100644 index 000000000..5b1d15f41 --- /dev/null +++ b/rmf_websocket/websocketpp/CMakeLists.txt @@ -0,0 +1,76 @@ + +############ Setup project and cmake +# Minimum cmake requirement. We should require a quite recent +# cmake for the dependency find macros etc. to be up to date. +cmake_minimum_required (VERSION 3.10) + +############ Paths + +set (WEBSOCKETPP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) +set (WEBSOCKETPP_INCLUDE ${WEBSOCKETPP_ROOT}/websocketpp) +set (WEBSOCKETPP_BUILD_ROOT ${CMAKE_CURRENT_BINARY_DIR}) +set (WEBSOCKETPP_BIN ${WEBSOCKETPP_BUILD_ROOT}/bin) +set (WEBSOCKETPP_LIB ${WEBSOCKETPP_BUILD_ROOT}/lib) + +# CMake install step prefix. I assume linux users want the prefix to +# be the default /usr or /usr/local so this is only adjusted on Windows. +# This must be set prior to any call to project or it will not be read correctly. +# - Windows: Build the INSTALL project in your solution file. +# - Linux/OSX: make install. +if (WIN32) + set (CMAKE_INSTALL_PREFIX "${WEBSOCKETPP_ROOT}/install" CACHE PATH "") +endif () + +############ Project name and version +set (WEBSOCKETPP_MAJOR_VERSION 0) +set (WEBSOCKETPP_MINOR_VERSION 8) +set (WEBSOCKETPP_PATCH_VERSION 3) +set (WEBSOCKETPP_VERSION ${WEBSOCKETPP_MAJOR_VERSION}.${WEBSOCKETPP_MINOR_VERSION}.${WEBSOCKETPP_PATCH_VERSION}) + +if(POLICY CMP0048) + cmake_policy(GET CMP0048 _version_policy) +endif() + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +include(GNUInstallDirs) + +set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") +if (WIN32 AND NOT CYGWIN) + set (DEF_INSTALL_CMAKE_DIR cmake) +else () + set (DEF_INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/websocketpp) +endif () +set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") + +# Make relative paths absolute (needed later on) +foreach (p INCLUDE CMAKE) + set (var INSTALL_${p}_DIR) + if (NOT IS_ABSOLUTE "${${var}}") + set (${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") + endif () +endforeach () + +# Set CMake library search policy +if (COMMAND cmake_policy) + cmake_policy (SET CMP0003 NEW) + cmake_policy (SET CMP0005 NEW) +endif () + +# Disable unnecessary build types +set (CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo;Debug" CACHE STRING "Configurations" FORCE) + +############ Build customization + +# Override from command line "CMake -D