### Add C++20 Hello World Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 hello world client example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(hello-world-client "20") target_link_libraries(asio-grpc-example-hello-world-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Hello World Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 hello world server example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(hello-world-server "20") target_link_libraries(asio-grpc-example-hello-world-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Multi-threaded Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 multi-threaded server example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(multi-threaded-server "20") target_link_libraries(asio-grpc-example-multi-threaded-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Streaming Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 streaming server example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(streaming-server "20") target_link_libraries(asio-grpc-example-streaming-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Multi-threaded Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 multi-threaded client example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(multi-threaded-client "20") target_link_libraries(asio-grpc-example-multi-threaded-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Unifex Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 Unifex server example, linking it with Asio-gRPC and the Unifex integration library. ```cmake asio_grpc_add_example(unifex-server "20") target_link_libraries(asio-grpc-example-unifex-server PRIVATE asio-grpc::asio-grpc-unifex) ``` -------------------------------- ### Add C++20 Unifex Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 Unifex client example, linking it with Asio-gRPC and the Unifex integration library. ```cmake asio_grpc_add_example(unifex-client "20") target_link_libraries(asio-grpc-example-unifex-client PRIVATE asio-grpc::asio-grpc-unifex) ``` -------------------------------- ### Install asio-grpc via CMake Source: https://github.com/tradias/asio-grpc/blob/master/README.md Build and install asio-grpc to a specified prefix using CMake. ```shell cmake -B build -DCMAKE_INSTALL_PREFIX=/desired/installation/directory . cmake --build build --target install ``` -------------------------------- ### Add Generic Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the generic server example executable, linking it with Asio-gRPC and Boost coroutine support. ```cmake asio_grpc_add_example(generic-server "17") target_link_libraries(asio-grpc-example-generic-server PRIVATE asio-grpc::asio-grpc Boost::coroutine) ``` -------------------------------- ### Add C++20 Streaming Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 streaming client example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(streaming-client "20") target_link_libraries(asio-grpc-example-streaming-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add Generic Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the generic client example executable, linking it with Asio-gRPC and Boost coroutine support. ```cmake asio_grpc_add_example(generic-client "17") target_link_libraries(asio-grpc-example-generic-client PRIVATE asio-grpc::asio-grpc Boost::coroutine) ``` -------------------------------- ### Add C++20 Async Generator Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 async generator server example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(async-generator-server "20") target_link_libraries(asio-grpc-example-async-generator-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Multi-threaded Alternative Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 multi-threaded alternative server example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(multi-threaded-alternative-server "20") target_link_libraries(asio-grpc-example-multi-threaded-alternative-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Multi-threaded Alternative Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 multi-threaded alternative client example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(multi-threaded-alternative-client "20") target_link_libraries(asio-grpc-example-multi-threaded-alternative-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Async Generator Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 async generator client example, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(async-generator-client "20") target_link_libraries(asio-grpc-example-async-generator-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Main IO Context Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 server example that uses the main IO context, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(main-io-context-server "20") target_link_libraries(asio-grpc-example-main-io-context-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Server-Side Hello World with Arena Allocation Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A server-side hello world example that utilizes google::protobuf::Arena for memory allocation. ```cpp // Server-side hello world with google::protobuf::Arena allocation ``` -------------------------------- ### Add C++20 Share IO Context Server Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 server example that shares an IO context, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(share-io-context-server "20") target_link_libraries(asio-grpc-example-share-io-context-server PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Link Backend Libraries for Examples Source: https://github.com/tradias/asio-grpc/blob/master/src/CMakeLists.txt Conditionally links backend libraries (Boost.Headers, asio::asio, unifex::unifex, STDEXEC::stdexec) to asio-grpc interface targets when examples are being built. This ensures necessary dependencies are available for example targets. ```cmake if(ASIO_GRPC_BUILD_EXAMPLES) target_link_libraries(asio-grpc INTERFACE Boost::headers) if(TARGET asio::asio) target_link_libraries(asio-grpc-standalone-asio INTERFACE asio::asio) endif() if(TARGET unifex::unifex) target_link_libraries(asio-grpc-unifex INTERFACE unifex::unifex) endif() if(TARGET STDEXEC::stdexec) target_link_libraries(asio-grpc-stdexec INTERFACE STDEXEC::stdexec) endif() endif() ``` -------------------------------- ### Single-Threaded gRPC Client Source: https://github.com/tradias/asio-grpc/blob/master/doc/client_rpc_cheat_sheet.md A basic example of a single-threaded gRPC client setup. This serves as a starting point for making RPC calls. ```cpp #include #include "example/proto/example.grpc.pb.h" int main(int argc, char** argv) { auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); auto stub = example::v1::ExampleService::NewStub(channel); grpc::ClientContext context; example::v1::Request request; example::v1::Response response; request.set_input("hello world"); grpc::Status status = stub->Unary(&context, request, &response); if (status.ok()) { std::cout << "Response: " << response.output() << std::endl; } else { std::cerr << status.error_code() << ": " << status.error_message() << std::endl; } return 0; } ``` -------------------------------- ### Add C++20 Share IO Context Client Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 client example that shares an IO context, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(share-io-context-client "20") target_link_libraries(asio-grpc-example-share-io-context-client PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Add C++20 Hello World Server Arena Example Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Configures the C++20 hello world server example using arena allocation, linking it with Asio-gRPC. ```cmake asio_grpc_add_example(hello-world-server-arena "20") target_link_libraries(asio-grpc-example-hello-world-server-arena PRIVATE asio-grpc::asio-grpc) ``` -------------------------------- ### Define Asio-gRPC Example Helper Library Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt This snippet defines an interface library to include common helper directories for Asio-gRPC examples. ```cmake add_library(asio-grpc-example-helper INTERFACE) target_include_directories(asio-grpc-example-helper INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/helper") ``` -------------------------------- ### Install Git Hooks Source: https://github.com/tradias/asio-grpc/blob/master/CONTRIBUTING.md Install git hooks for the asio-grpc project after setting up clang-format and cmake-format. This step ensures code quality and consistency before committing. ```shell cmake --build --preset default --target asio-grpc-init-git-hooks ``` -------------------------------- ### Link asio-grpc after CMake installation with Boost.Asio Source: https://github.com/tradias/asio-grpc/blob/master/README.md Configure CMake to find asio-grpc installed in a custom prefix and link against Boost.Asio. ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory find_package(asio-grpc CONFIG REQUIRED) find_package(Boost) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc Boost::headers) ``` -------------------------------- ### Link asio-grpc after CMake installation with libunifex Source: https://github.com/tradias/asio-grpc/blob/master/README.md Configure CMake to find asio-grpc installed in a custom prefix and link against libunifex. ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory find_package(asio-grpc CONFIG REQUIRED) find_package(unifex) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-unifex unifex::unifex) ``` -------------------------------- ### Single-Threaded gRPC Server Main Source: https://github.com/tradias/asio-grpc/blob/master/doc/server_rpc_cheat_sheet.md Basic setup for a single-threaded gRPC server using Asio-gRPC. This is the entry point for the server application. ```cpp #include #include #include #include #include #include #include #include #include #include #include #include "example/v1/example.grpc.pb.h" #include #include #include #include using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::Status; using example::v1::Example; using example::v1::ExampleRequest; using example::v1::ExampleResponse; // Implementation of the Example service. class ExampleServiceImpl final : public Example::Service { public: Status SayHello(ServerContext* context, const ExampleRequest* request, ExampleResponse* response) override { response->set_message("Hello " + request->name()); return Status::OK; } }; void RunServer() { std::string server_address("0.0.0.0:50051"); ExampleServiceImpl service; ServerBuilder builder; // Listen on the given address without any authentication mechanism. builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); // Register "service" as the instance through which we'll communicate with // clients. The server owns the service object and decides how long to keep // it up. builder.RegisterService(&service); // Assemble the server. std::unique_ptr server(builder.BuildAndStart()); std::cout << "Server listening on " << server_address << std::endl; // Wait for the server to shutdown. Note that some other thread must be // responsible for calling shutdown() on the server in a real world scenario. server->Wait(); } int main(int argc, char** argv) { RunServer(); return 0; } ``` -------------------------------- ### Fetch asio-grpc using FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md Use CMake's FetchContent module to download and make asio-grpc available in your project. This example fetches version v3.7.0. ```cmake include(FetchContent) FetchContent_Declare( asio-grpc GIT_REPOSITORY https://github.com/Tradias/asio-grpc.git GIT_TAG v3.7.0 SYSTEM) FetchContent_MakeAvailable(asio-grpc) ``` -------------------------------- ### Server-side Main io_context Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md Example showing how to use an io_context as the main context and a GrpcContext on a separate thread for gRPC servers. ```cpp // Example showing how to use an io_context as the main context and a GrpcContext on a separate thread for gRPC servers. ``` -------------------------------- ### CMake Example for Protobuf Generation Source: https://github.com/tradias/asio-grpc/blob/master/doc/cmake_protobuf_generate.md This example demonstrates how to use the `asio_grpc_protobuf_generate` function in CMake to process a Protobuf file. It defines a target that depends on the generated files, ensuring they are compiled when the source .proto file changes. ```cmake add_library(target-option ${PROTOBUF_GENERATED_FILES} ${PROTOBUF_GENERATED_HEADERS} ${GRPC_GENERATED_FILES} ${GRPC_GENERATED_HEADERS} ${GRPC_MOCK_GENERATED_HEADERS} ) # Add include directories target_include_directories(target-option PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) # Add dependencies target_link_libraries(target-option PRIVATE protobuf grpc++) # Generate the code asio_grpc_protobuf_generate(target/target.proto) ``` -------------------------------- ### Add Example Executable Function Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt This function simplifies adding new example executables by setting up sources, linking libraries, and defining compile options based on the C++ standard. ```cmake function(asio_grpc_add_example _asio_grpc_name _asio_grpc_cxx_standard) add_executable(asio-grpc-example-${_asio_grpc_name}) target_sources(asio-grpc-example-${_asio_grpc_name} PRIVATE ${_asio_grpc_name}.cpp) convert_to_cpp_suffix(${_asio_grpc_cxx_standard}) target_link_libraries( asio-grpc-example-${_asio_grpc_name} PRIVATE asio-grpc-example-helper asio-grpc-compile-options${_asio_grpc_cxx_standard} asio-grpc-example-protos${_asio_grpc_cxx_standard}) target_compile_options( asio-grpc-example-${_asio_grpc_name} PRIVATE $<$,$>: -Wsign-conversion -Wshadow>) endfunction() ``` -------------------------------- ### Build Project with CMake Source: https://github.com/tradias/asio-grpc/blob/master/CONTRIBUTING.md Build the asio-grpc project, including tests and examples, using CMake presets. This command compiles the source code after configuration. ```shell cmake --build --preset default ``` -------------------------------- ### Share io_context for gRPC Clients Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md This example demonstrates how to run an io_context and a GrpcContext on the same thread for gRPC client applications. ```cpp // Example showing how to run an io_context and a GrpcContext on the same thread for gRPC clients. ``` -------------------------------- ### Add asio-grpc via CPM.cmake from GitHub Source: https://github.com/tradias/asio-grpc/blob/master/README.md Use CPM.cmake to fetch and add asio-grpc directly from its GitHub repository. This example links the Boost.Asio backend. ```cmake CPMAddPackage( NAME asio-grpc GITHUB_REPOSITORY Tradias/asio-grpc VERSION 3.7.0 ) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc) ``` -------------------------------- ### Link asio-grpc after CMake installation with standalone Asio Source: https://github.com/tradias/asio-grpc/blob/master/README.md Configure CMake to find asio-grpc installed in a custom prefix and link against standalone Asio. ```cmake # Make sure CMAKE_PREFIX_PATH contains /desired/installation/directory find_package(asio-grpc CONFIG REQUIRED) find_package(asio) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-standalone-asio asio::asio) ``` -------------------------------- ### gRPC Client Hello World with C++20 Coroutines Source: https://github.com/tradias/asio-grpc/blob/master/README.md Example of a gRPC client making a 'SayHello' RPC call using C++20 coroutines and asio::awaitable. Ensure the gRPC server is running on localhost:50051. The RPC status is asserted to be OK. ```cpp helloworld::Greeter::Stub stub(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials())); asio::co_spawn( grpc_context, [&]() -> asio::awaitable { using RPC = agrpc::ClientRPC<&helloworld::Greeter::Stub::PrepareAsyncSayHello>; grpc::ClientContext client_context; helloworld::HelloRequest request; request.set_name("world"); helloworld::HelloReply response; const grpc::Status status = co_await RPC::request(grpc_context, stub, client_context, request, response, asio::use_awaitable); assert(status.ok()); }, asio::detached); grpc_context.run(); ``` -------------------------------- ### Link with gRPC using find_package Source: https://github.com/tradias/asio-grpc/blob/master/README.md This snippet demonstrates linking your application with gRPC when using asio-grpc as a subdirectory. This is a common setup for gRPC-based applications. ```cmake find_package(gRPC) target_link_libraries(your_app PUBLIC gRPC::grpc++) ``` -------------------------------- ### Multi-threaded Client (Multiple GrpcContexts) Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md An example of a multi-threaded client utilizing multiple GrpcContexts for concurrent operations. ```cpp // Multi-threaded client using multiple GrpcContexts ``` -------------------------------- ### Bidirectional-Streaming RPC with Thread Pool Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A bidirectional-streaming RPC example demonstrating how to dispatch requests to a thread pool and write responses back to the client. ```cpp // The following bidirectional-streaming example shows how to dispatch requests to a thread_pool and write responses // back to the client. ``` -------------------------------- ### Run io_context and GrpcContext on the Same Thread (until GrpcContext stops) Source: https://github.com/tradias/asio-grpc/blob/master/doc/using_asio_io_context.md This example demonstrates running both the io_context and GrpcContext on the same thread, with the execution continuing until the GrpcContext stops. ```cpp #include #include void agrpc_run_io_context_and_grpc_context( boost::asio::io_context& io_context, grpc_context& grpc_context) { co_spawn(io_context, [&]() mutable { auto timer = std::make_unique(io_context); timer->async_wait([&](auto&& PH1) { grpc_context.stop(); }); }); grpc_context.run(); } ``` -------------------------------- ### Explicitly Constructed io_context and GrpcContext (Coroutine) Source: https://github.com/tradias/asio-grpc/blob/master/doc/using_asio_io_context.md This example demonstrates creating an io_context and GrpcContext explicitly. The io_context is used as the main context, and its completion signals the GrpcContext to stop. ```cpp #include #include #include #include #include using namespace boost::asio; void co_spawn_io_context_and_grpc_context( io_context& io_context, grpc_context& grpc_context) { co_spawn(io_context, [&]() mutable { auto timer = std::make_unique(io_context); timer->async_wait([&](auto&& PH1) { grpc_context.stop(); }); }, detached); co_return; } ``` -------------------------------- ### Sharing io_context for gRPC Servers Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md An example demonstrating how to run an io_context and a GrpcContext on the same thread for gRPC servers. This is useful when an HTTP server needs to interact with a gRPC server without creating a separate thread for the GrpcContext. ```cpp // Example showing how to run an io_context and a GrpcContext on the same thread for gRPC servers. // This can i.e. be useful when writing an HTTP server that occasionally reaches out to a gRPC server. In that case // creating a separate thread for the GrpcContext might be undesirable due to added synchronization complexity. ``` -------------------------------- ### Bidirectional-Streaming RPC Implementation Source: https://github.com/tradias/asio-grpc/blob/master/doc/server_rpc_cheat_sheet.md Handles bidirectional-streaming RPCs where both the client and server can send a sequence of messages. This example demonstrates reading from the client and writing responses asynchronously. ```cpp Status SayHelloBothStream(ServerContext* context, ServerBidiReactor* reactor) override { // This is a simplified example. In a real-world scenario, you would likely // spawn asynchronous tasks to handle reading from the client and writing // responses concurrently. ExampleRequest request; while (reactor->Read(&request)) { ExampleResponse response; response.set_message("Hello " + request.name()); reactor->Write(response); } reactor->Finish(Status::OK); return Status::OK; } ``` -------------------------------- ### Conditional Instantiation for C++20 Tests and Examples Source: https://github.com/tradias/asio-grpc/blob/master/test/utils/CMakeLists.txt Conditionally instantiates test utilities for various Asio backends (Boost.Asio, Standalone Asio, Unifex) and C++20 standard when `ASIO_GRPC_ENABLE_CPP20_TESTS_AND_EXAMPLES` is enabled. ```cmake if(ASIO_GRPC_ENABLE_CPP20_TESTS_AND_EXAMPLES) asio_grpc_add_test_util(asio-grpc-test-util-boost-asio-cpp20 "BOOST_ASIO" "20") asio_grpc_add_test_util(asio-grpc-test-util-standalone-asio-cpp20 "STANDALONE_ASIO" "20") asio_grpc_add_test_util(asio-grpc-test-util-unifex-cpp20 "UNIFEX" "20") asio_grpc_add_test_util(asio-grpc-test-util-boost-asio-unifex-cpp20 "BOOST_ASIO" "20" "unifex") if(ASIO_GRPC_ENABLE_STDEXEC_TESTS) asio_grpc_add_test_util(asio-grpc-test-util-stdexec-cpp20 "STDEXEC" "20") asio_grpc_add_test_util(asio-grpc-test-util-standalone-asio-stdexec-cpp20 "STANDALONE_ASIO" "20" "stdexec") endif() endif() ``` -------------------------------- ### Generic Bidirectional-Streaming RPC with Thread Pool Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A bidirectional-streaming example that dispatches requests to a thread pool and writes responses back to the client. ```cpp // A bidirectional-streaming example that shows how to dispatch requests to a thread_pool and write responses // back to the client. ``` -------------------------------- ### Server-Side Hello World Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A basic server-side hello world implementation that handles a single client request before shutting down. ```cpp // Server-side hello world which handles exactly one request from the client before shutting down. ``` -------------------------------- ### Clone and Bootstrap vcpkg Source: https://github.com/tradias/asio-grpc/blob/master/CONTRIBUTING.md Clone the vcpkg repository and bootstrap it to manage project dependencies. This is a prerequisite for building the asio-grpc project. ```shell git clone https://github.com/microsoft/vcpkg ./vcpkg/bootstrap-vcpkg.bat # or bootstrap-vcpkg.sh on Linux ``` -------------------------------- ### Link with standalone Asio after FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md Link your application against asio-grpc and standalone Asio after using FetchContent to include asio-grpc. Ensure Asio is available. ```cmake find_package(asio) # or FetchContent equivalent target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-standalone-asio asio::asio) ``` -------------------------------- ### Configure Project with CMake Source: https://github.com/tradias/asio-grpc/blob/master/CONTRIBUTING.md Configure the asio-grpc project using CMake presets. Ensure the VCPKG_ROOT environment variable is set to the cloned vcpkg repository directory. ```shell cmake --preset default ``` -------------------------------- ### Link with Boost.Asio after FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md Link your application against asio-grpc and Boost.Asio after using FetchContent to include asio-grpc. Ensure Boost is available. ```cmake find_package(Boost) # or FetchContent equivalent target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc Boost::headers) ``` -------------------------------- ### Get Target Interface Sources Source: https://github.com/tradias/asio-grpc/blob/master/test/syntax/CMakeLists.txt Retrieves the interface sources for a given target. This is often used to access header files. ```cmake get_target_property(_asio_grpc_headers asio-grpc-sources INTERFACE_SOURCES) ``` -------------------------------- ### Determine Build Test Generator Source: https://github.com/tradias/asio-grpc/blob/master/test/cmake/CMakeLists.txt Sets the generator for CMake installation tests based on the CMAKE_GENERATOR. This ensures compatibility with different build environments. ```cmake if("${CMAKE_GENERATOR}" STREQUAL "Ninja Multi-Config") if(WIN32) set(ASIO_GRPC_CMAKE_INSTALL_TEST_GENERATOR "Ninja") else() set(ASIO_GRPC_CMAKE_INSTALL_TEST_GENERATOR "Unix Makefiles") endif() else() set(ASIO_GRPC_CMAKE_INSTALL_TEST_GENERATOR "${CMAKE_GENERATOR}") endif() ``` -------------------------------- ### vcpkg.json for asio-grpc Dependencies Source: https://github.com/tradias/asio-grpc/blob/master/README.md Specify asio-grpc and optional Asio backends (Boost.Asio, standalone Asio, libunifex, stdexec) in your vcpkg.json file. ```json { "name": "your_app", "version": "0.1.0", "dependencies": [ "asio-grpc", // To use the Boost.Asio backend add // "boost-asio", // To use the standalone Asio backend add // "asio", // To use the libunifex backend add // "libunifex", // To use the stdexec backend add // "stdexec" ] } ``` -------------------------------- ### Instantiate Test Utility for Boost.Asio C++17 Source: https://github.com/tradias/asio-grpc/blob/master/test/utils/CMakeLists.txt Calls the `asio_grpc_add_test_util` function to create a test utility library for Boost.Asio with C++17 standard. ```cmake asio_grpc_add_test_util(asio-grpc-test-util-boost-asio "BOOST_ASIO" "17") ``` -------------------------------- ### Link with libunifex after FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md Link your application against asio-grpc and libunifex after using FetchContent to include asio-grpc. Ensure libunifex is available. ```cmake find_package(unifex) # or FetchContent equivalent target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-unifex unifex::unifex) ``` -------------------------------- ### Add asio-grpc subdirectory with libunifex Source: https://github.com/tradias/asio-grpc/blob/master/README.md Integrate asio-grpc by adding its source directory as a subdirectory and link against libunifex. Ensure libunifex is found. ```cmake add_subdirectory(/path/to/asio-grpc SYSTEM) find_package(unifex) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-unifex unifex::unifex) ``` -------------------------------- ### Server-side Unifex Unary Request Handler Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md Register a request handler to unary requests. A bit of boilerplate code regarding stop_source has been added to make the example testable. ```cpp // Register a request handler to unary requests. A bit of boilerplate code regarding stop_source has been added to make // the example testable. ``` -------------------------------- ### Configure Boost.Asio Documentation Targets Source: https://github.com/tradias/asio-grpc/blob/master/example/snippets/CMakeLists.txt Conditionally adds documentation targets for Boost.Asio when C++20 coroutines are available and tests/examples are enabled. Links against the main Asio-gRPC library. ```cmake if(ASIO_GRPC_BOOST_ASIO_HAS_CO_AWAIT AND ASIO_GRPC_ENABLE_CPP20_TESTS_AND_EXAMPLES) asio_grpc_add_documentation( asio-grpc-documentation-boost-asio "alarm.cpp" "client.cpp" "client_callback.cpp" "client_rpc.cpp" "server.cpp" "server_callback.cpp" "server_rpc.cpp" "io_context.cpp") target_link_libraries(asio-grpc-documentation-boost-asio PRIVATE asio-grpc::asio-grpc) asio_grpc_add_documentation(asio-grpc-documentation-unifex "unifex_client.cpp" "unifex_server.cpp") target_link_libraries(asio-grpc-documentation-unifex PRIVATE asio-grpc::asio-grpc-unifex) endif() ``` -------------------------------- ### Add asio-grpc subdirectory with standalone Asio Source: https://github.com/tradias/asio-grpc/blob/master/README.md Integrate asio-grpc by adding its source directory as a subdirectory and link against standalone Asio. Ensure Asio is found. ```cmake add_subdirectory(/path/to/asio-grpc SYSTEM) find_package(asio) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-standalone-asio asio::asio) ``` -------------------------------- ### Instantiate Test Utility for Standalone Asio C++17 Source: https://github.com/tradias/asio-grpc/blob/master/test/utils/CMakeLists.txt Calls the `asio_grpc_add_test_util` function to create a test utility library for Standalone Asio with C++17 standard. ```cmake asio_grpc_add_test_util(asio-grpc-test-util-standalone-asio "STANDALONE_ASIO" "17") ``` -------------------------------- ### Link asio-grpc with libunifex using CMake Source: https://github.com/tradias/asio-grpc/blob/master/README.md Find the asio-grpc and libunifex packages, then link your target against the respective libraries. ```cmake find_package(asio-grpc CONFIG REQUIRED) find_package(unifex CONFIG REQUIRED) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-unifex unifex::unifex) ``` -------------------------------- ### Link with gRPC after FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md After fetching asio-grpc using FetchContent, link your application against gRPC. This assumes gRPC is also managed or available. ```cmake target_link_libraries(your_app PUBLIC gRPC::grpc++) ``` -------------------------------- ### Link with stdexec after FetchContent Source: https://github.com/tradias/asio-grpc/blob/master/README.md Link your application against asio-grpc and stdexec after using FetchContent to include asio-grpc. Ensure stdexec is available. ```cmake find_package(stdexec) # or FetchContent equivalent target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-stdexec STDEXEC::stdexec) ``` -------------------------------- ### Using Sender with libunifex for RPCs Source: https://github.com/tradias/asio-grpc/blob/master/doc/completion_token.md Illustrates how to use `agrpc::use_sender` to return a Sender for asynchronous RPC processing with `co_await` and `unifex::task`. ```C++ auto rpc = agrpc::call(stub.AsyncSayHello, request, agrpc::use_sender(context)); unifex::task task = [&]() -> unifex::task { auto response = co_await rpc; EXPECT_EQ(response.message(), "Hello"); }; task(); agrpc::run(context); EXPECT_TRUE(task.is_done()); ``` -------------------------------- ### Add asio-grpc subdirectory with stdexec Source: https://github.com/tradias/asio-grpc/blob/master/README.md Integrate asio-grpc by adding its source directory as a subdirectory and link against stdexec. Ensure stdexec is found. ```cmake add_subdirectory(/path/to/asio-grpc SYSTEM) find_package(stdexec) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-stdexec STDEXEC::stdexec) ``` -------------------------------- ### Link asio-grpc with standalone Asio using CMake Source: https://github.com/tradias/asio-grpc/blob/master/README.md Find the asio-grpc and standalone Asio packages, then link your target against the appropriate libraries. ```cmake find_package(asio-grpc CONFIG REQUIRED) find_package(asio CONFIG REQUIRED) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-standalone-asio asio::asio) ``` -------------------------------- ### Link asio-grpc with Boost.Asio using CMake Source: https://github.com/tradias/asio-grpc/blob/master/README.md Find the asio-grpc package and link your target against asio-grpc and Boost.Asio headers. ```cmake find_package(asio-grpc CONFIG REQUIRED) find_package(Boost REQUIRED) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc Boost::headers) ``` -------------------------------- ### Add asio-grpc subdirectory with Boost.Asio Source: https://github.com/tradias/asio-grpc/blob/master/README.md Integrate asio-grpc by adding its source directory as a subdirectory in your CMake project and link against Boost.Asio. Ensure Boost is found. ```cmake add_subdirectory(/path/to/asio-grpc SYSTEM) find_package(Boost) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc Boost::headers) ``` -------------------------------- ### Client-Streaming RPC Client Source: https://github.com/tradias/asio-grpc/blob/master/doc/client_rpc_cheat_sheet.md Illustrates how to implement a client-streaming RPC. The client sends a sequence of messages to the server and receives a single response. ```cpp #include #include "example/proto/example.grpc.pb.h" void ClientStreamingRpc(std::shared_ptr channel) { auto stub = example::v1::ExampleService::NewStub(channel); grpc::ClientContext context; example::v1::Request request; example::v1::Response response; std::unique_ptr> writer( stub->ClientStreaming(&context, &response)); for (int i = 0; i < 3; ++i) { request.set_input("Client Streaming Message " + std::to_string(i)); if (!writer->Write(request)) { // Broken stream. break; } } writer->WritesDone(); grpc::Status status = writer->Finish(); if (status.ok()) { std::cout << "Client Streaming RPC Response: " << response.output() << std::endl; } else { std::cerr << "Client Streaming RPC Error: " << status.error_message() << std::endl; } } ``` -------------------------------- ### Add Documentation Snippets Subdirectory Source: https://github.com/tradias/asio-grpc/blob/master/example/CMakeLists.txt Includes the 'snippets' subdirectory if Asio-gRPC tests are enabled, likely for documentation generation or testing purposes. ```cmake if(ASIO_GRPC_BUILD_TESTS) add_subdirectory(snippets) endif() ``` -------------------------------- ### Unary RPC Client Source: https://github.com/tradias/asio-grpc/blob/master/doc/client_rpc_cheat_sheet.md Demonstrates how to perform a unary RPC call from the client. This is the simplest form of RPC where a single request is sent and a single response is received. ```cpp #include #include "example/proto/example.grpc.pb.h" void UnaryRpc(std::shared_ptr channel) { auto stub = example::v1::ExampleService::NewStub(channel); grpc::ClientContext context; example::v1::Request request; example::v1::Response response; request.set_input("Unary RPC"); grpc::Status status = stub->Unary(&context, request, &response); if (status.ok()) { std::cout << "Unary RPC Response: " << response.output() << std::endl; } else { std::cerr << "Unary RPC Error: " << status.error_message() << std::endl; } } ``` -------------------------------- ### Link Libraries for Main Executable Source: https://github.com/tradias/asio-grpc/blob/master/test/cmake/subdirectory/src/CMakeLists.txt Links the necessary libraries to the 'main' executable. This includes asio-grpc, Asio, and gRPC++ libraries. ```cmake target_link_libraries(main PRIVATE asio-grpc::asio-grpc-standalone-asio asio::asio gRPC::grpc++_unsecure) ``` -------------------------------- ### Generate gRPC and Mock Code from Protobuf Source: https://github.com/tradias/asio-grpc/blob/master/test/proto/CMakeLists.txt Generates C++ source files for gRPC services and mock implementations from Protocol Buffer definitions. Specify output variables, directories, import paths, and the proto files to process. ```cmake asio_grpc_protobuf_generate( GENERATE_GRPC GENERATE_MOCK_CODE OUT_VAR "ASIO_GRPC_TEST_PROTO_SOURCES" OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated" IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}" PROTOS "${CMAKE_CURRENT_SOURCE_DIR}/grpc/health/v1/health.proto" "${CMAKE_CURRENT_SOURCE_DIR}/test/v1/test.proto" "${CMAKE_CURRENT_SOURCE_DIR}/test/msg/message.proto") ``` -------------------------------- ### Find gRPC and Asio Packages Source: https://github.com/tradias/asio-grpc/blob/master/test/cmake/subdirectory/src/CMakeLists.txt Locates and makes the gRPC and Asio libraries available for the project. The 'REQUIRED' keyword ensures that the build fails if these packages are not found. ```cmake find_package(gRPC REQUIRED) find_package(asio REQUIRED) ``` -------------------------------- ### Link asio-grpc with stdexec using CMake Source: https://github.com/tradias/asio-grpc/blob/master/README.md Find the asio-grpc and stdexec packages, then link your target against the corresponding libraries. ```cmake find_package(asio-grpc CONFIG REQUIRED) find_package(stdexec CONFIG REQUIRED) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-stdexec STDEXEC::stdexec) ``` -------------------------------- ### Configure Asio-gRPC Source Files for Testing Source: https://github.com/tradias/asio-grpc/blob/master/src/CMakeLists.txt Selects header files for the 'asio-grpc-sources' interface target when tests are enabled and header syntax checking is active. It filters out specific header files based on build configurations like ASIO_GRPC_TEST_CALLBACK_API. ```cmake if(ASIO_GRPC_BUILD_TESTS AND ASIO_GRPC_ENABLE_CHECK_HEADER_SYNTAX_TARGET) add_library(asio-grpc-sources INTERFACE) file(GLOB_RECURSE _asio_grpc_sources "agrpc/*.hpp") list( TRANSFORM _asio_grpc_sources REPLACE "(execution_stdexec.hpp|association_execution.hpp|health_check_service.hpp|grpc_context_definition.hpp)$" "") if(NOT ASIO_GRPC_TEST_CALLBACK_API) list(TRANSFORM _asio_grpc_sources REPLACE "(reactor_ptr.hpp|server_callback.hpp|server_callback_coroutine.hpp|client_callback.hpp)$" "") elseif(NOT ASIO_GRPC_TEST_CALLBACK_API_CPP20) list(TRANSFORM _asio_grpc_sources REPLACE "(server_callback_coroutine.hpp)$" "") endif() target_sources(asio-grpc-sources INTERFACE ${_asio_grpc_sources}) endif() ``` -------------------------------- ### Run io_context and GrpcContext on the Same Thread (until both stop) Source: https://github.com/tradias/asio-grpc/blob/master/doc/using_asio_io_context.md This snippet shows how to run both io_context and GrpcContext on the same thread, with execution continuing until both contexts stop. This involves shared work tracking. ```cpp #include #include #include #include #include using namespace boost::asio; void agrpc_run_io_context_shared_work_tracking( io_context& io_context, grpc_context& grpc_context) { auto work_guard = boost::asio::make_work_guard(io_context, grpc_context); co_spawn(io_context, [&, work_guard = std::move(work_guard)]() mutable { auto timer = std::make_unique(io_context); timer->async_wait([&](auto&& PH1) mutable { work_guard.reset(); }); }); co_spawn(grpc_context, [&, work_guard = std::move(work_guard)]() mutable { auto timer = std::make_unique(*reinterpret_cast(&grpc_context)); timer->async_wait([&](auto&& PH1) mutable { work_guard.reset(); }); }); co_return; } ``` -------------------------------- ### Generate Protobuf Sources for Asio-gRPC Source: https://github.com/tradias/asio-grpc/blob/master/example/proto/CMakeLists.txt Use this macro to generate C++ source files from Protobuf definitions. It supports generating gRPC and mock code, specifying output variables and directories, import paths, and the Protobuf files themselves. ```cmake asio_grpc_protobuf_generate( GENERATE_GRPC GENERATE_MOCK_CODE OUT_VAR "ASIO_GRPC_EXAMPLE_PROTO_SOURCES" OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated" IMPORT_DIRS "${CMAKE_CURRENT_LIST_DIR}" PROTOS "${CMAKE_CURRENT_LIST_DIR}/helloworld/helloworld.proto" "${CMAKE_CURRENT_LIST_DIR}/grpc/health/v1/health.proto" "${CMAKE_CURRENT_LIST_DIR}/example/v1/example.proto" "${CMAKE_CURRENT_LIST_DIR}/example/v1/example_ext.proto") ``` -------------------------------- ### Link with stdexec using find_package Source: https://github.com/tradias/asio-grpc/blob/master/README.md This snippet shows how to link your application with asio-grpc and stdexec when using find_package. Ensure CMAKE_PREFIX_PATH is set correctly. ```cmake find_package(asio-grpc CONFIG REQUIRED) find_package(stdexec) target_link_libraries(your_app PUBLIC asio-grpc::asio-grpc-stdexec STDEXEC::stdexec) ``` -------------------------------- ### Run Tests with CTest Source: https://github.com/tradias/asio-grpc/blob/master/CONTRIBUTING.md Execute all tests for the asio-grpc project using CTest with the default preset. This ensures the project's functionality and stability. ```shell ctest --preset default ``` -------------------------------- ### Client RPC Client-Streaming Call Migration Source: https://github.com/tradias/asio-grpc/blob/master/doc/v3_migration.md This snippet demonstrates the v3 migration for a full client-streaming RPC call, contrasting with the v2 method. ```cpp #include #include #include #include // ... auto [response, status] = agrpc::rpc_client_streaming( example::v1::Greeter::Stub::NewStub(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials())), &example::v1::Greeter::Stub::StubInterface::LotsOfReplies, grpc::ClientContext{}, [](auto& writer) { writer.Write(example::v1::HelloRequest{ "foo" }); writer.Write(example::v1::HelloRequest{ "bar" }); } ); // ... ``` -------------------------------- ### Define Asio-gRPC Interface Target Source: https://github.com/tradias/asio-grpc/blob/master/src/CMakeLists.txt Creates an interface library target for asio-grpc, setting C++17 standard and include directories. Use this to define common configurations for different backends. ```cmake function(asio_grpc_create_interface_target _asio_grpc_name) add_library(${_asio_grpc_name} INTERFACE) add_library(${PROJECT_NAME}::${_asio_grpc_name} ALIAS ${_asio_grpc_name}) target_compile_features(${_asio_grpc_name} INTERFACE cxx_std_17) target_include_directories(${_asio_grpc_name} INTERFACE "$" $) endfunction() asio_grpc_create_interface_target(asio-grpc) target_compile_definitions(asio-grpc INTERFACE AGRPC_BOOST_ASIO) asio_grpc_create_interface_target(asio-grpc-standalone-asio) target_compile_definitions(asio-grpc-standalone-asio INTERFACE AGRPC_STANDALONE_ASIO) asio_grpc_create_interface_target(asio-grpc-unifex) target_compile_definitions(asio-grpc-unifex INTERFACE AGRPC_UNIFEX) asio_grpc_create_interface_target(asio-grpc-stdexec) target_compile_definitions(asio-grpc-stdexec INTERFACE AGRPC_STDEXEC) target_compile_features(asio-grpc-stdexec INTERFACE cxx_std_20) ``` -------------------------------- ### Client-Streaming RPC Handler (C++20 Coroutines) Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A simple client-streaming RPC handler implemented using C++20 coroutines. ```cpp // A simple client-streaming rpc handler using C++20 coroutines. ``` -------------------------------- ### Server-Streaming RPC Client Source: https://github.com/tradias/asio-grpc/blob/master/doc/client_rpc_cheat_sheet.md Shows how to perform a server-streaming RPC. The client sends a single request and receives a stream of responses from the server. ```cpp #include #include "example/proto/example.grpc.pb.h" void ServerStreamingRpc(std::shared_ptr channel) { auto stub = example::v1::ExampleService::NewStub(channel); grpc::ClientContext context; example::v1::Request request; example::v1::Response response; request.set_input("Server Streaming Request"); std::unique_ptr> reader( stub->ServerStreaming(&context, request)); while (reader->Read(&response)) { std::cout << "Server Streaming RPC Response: " << response.output() << std::endl; } grpc::Status status = reader->Finish(); if (!status.ok()) { std::cerr << "Server Streaming RPC Error: " << status.error_message() << std::endl; } } ``` -------------------------------- ### Add Asio-gRPC Documentation Library Source: https://github.com/tradias/asio-grpc/blob/master/example/snippets/CMakeLists.txt Defines a CMake function to add a library for documentation targets. It compiles sources as objects and links against helper, proto, and compile option libraries. ```cmake function(asio_grpc_add_documentation _asio_grpc_name) add_library(${_asio_grpc_name} OBJECT) target_sources(${_asio_grpc_name} PRIVATE ${ARGN}) target_link_libraries(${_asio_grpc_name} PRIVATE asio-grpc-example-helper asio-grpc-example-protos-cpp20 asio-grpc-compile-options-cpp20) endfunction() ``` -------------------------------- ### Server-Streaming RPC Handler (C++20 Coroutines) Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md A simple server-streaming RPC handler implemented using C++20 coroutines. ```cpp // A simple server-streaming rpc handler using C++20 coroutines. ``` -------------------------------- ### Client RPC Server-Streaming Call Migration Source: https://github.com/tradias/asio-grpc/blob/master/doc/v3_migration.md This snippet illustrates the v3 migration for a full server-streaming RPC call, showing the updated client-side implementation. ```cpp #include #include #include #include // ... auto [response, status] = agrpc::rpc_server_streaming( example::v1::Greeter::Stub::NewStub(grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials())), &example::v1::Greeter::Stub::StubInterface::LotsOfGreetings, grpc::ClientContext{}, example::v1::HelloRequest{ "world" } ); // ... ``` -------------------------------- ### Multi-threaded Client (Single GrpcContext) Source: https://github.com/tradias/asio-grpc/blob/master/example/README.md An alternative approach to a multi-threaded client using a single GrpcContext. ```cpp // Multi-threaded client using single a GrpcContext ```