{"id":19835900,"url":"https://github.com/thequantumphysicist/asyncjsonrpc","last_synced_at":"2026-04-21T16:36:18.088Z","repository":{"id":159459568,"uuid":"197246892","full_name":"TheQuantumPhysicist/AsyncJsonRPC","owner":"TheQuantumPhysicist","description":"A simple, thread-safe, header-only library for asynchronous json rpc with context-per-call support","archived":false,"fork":false,"pushed_at":"2019-07-21T23:07:03.000Z","size":1136,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-06-21T09:06:47.149Z","etag":null,"topics":["async","asynchronous","high-performance","json","jsonrpc","jsonrpc2","rpc","thread-pool","thread-safe"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheQuantumPhysicist.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-16T18:25:23.000Z","updated_at":"2019-07-21T23:07:04.000Z","dependencies_parsed_at":"2023-07-09T12:00:47.773Z","dependency_job_id":null,"html_url":"https://github.com/TheQuantumPhysicist/AsyncJsonRPC","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TheQuantumPhysicist/AsyncJsonRPC","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheQuantumPhysicist%2FAsyncJsonRPC","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheQuantumPhysicist%2FAsyncJsonRPC/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheQuantumPhysicist%2FAsyncJsonRPC/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheQuantumPhysicist%2FAsyncJsonRPC/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheQuantumPhysicist","download_url":"https://codeload.github.com/TheQuantumPhysicist/AsyncJsonRPC/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheQuantumPhysicist%2FAsyncJsonRPC/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32100518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T11:25:29.218Z","status":"ssl_error","status_checked_at":"2026-04-21T11:25:28.499Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","asynchronous","high-performance","json","jsonrpc","jsonrpc2","rpc","thread-pool","thread-safe"],"created_at":"2024-11-12T12:09:33.254Z","updated_at":"2026-04-21T16:36:18.068Z","avatar_url":"https://github.com/TheQuantumPhysicist.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AsyncJsonRPC library\n\n### Introduction\nThe AsyncJsonRPC library is a simple, header-only, high-performance, thread-safe library that acts as the backend of a remote json-rpc system. It can be both synchronous and asynchronous.\n\nThe library doesn't contain any communication protocol. The way it works, from a high-level perspective, is that you post a string containing the jsonrpc call [according to the jsonrpc 2.0 standard](https://www.jsonrpc.org/specification), and you will get a callback function called (of your choosing, defined with a closure) with the response.\n\n### Context-per-call support... OR... why another jsonrpc library?\n\nThe reason for developing this library is that I needed something that I couldn't find in any other jsonrpc library, which is passing a context with every call.\n\nImagine you're running an http server where you receive restful requests. A user might pass a request that is json-rpc. Given that authentication (whether it's username/password or API key) shouldn't be in the rpc-call itself, for security reasons, how would a handler know how to create a stateful response based on the user id or authentication token?\n\nThere are ways to solve this problem, by wrapping everything in stateful classes. But this doesn't only create a performance hit, but can easily create thread-safety problems and can complicate the design.\n\nAsyncJsonRPC for the rescue! So now, you can simply pass as many context variables to every RPC call in a thread-safe manner. Here's an example:\n\nNote: We're using a custom ThreadPool class, but you can also use an executor from boost::asio with [the executor interface](https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/reference/executor.html)\n\n```c++\n    // you can add as many context types as you want! It's variadic.\n    ThreadPool threadPool;\n    AsyncJsonRPC\u003cThreadPool, ContextType1, ContextType2\u003e rpc(threadPool);\n\n    // here we add a handler for the method \"mymethod\", which takes two json parameters, an integer and a string\n    rpc.addHandler(\n        [](const Json::Value\u0026 request, Json::Value\u0026 response, ContextType1 ctx1, ContextType2 ctx2) {\n            // handle the call with the context variables\n        },\n        \"mymethod\", {{\"p1\", Json::ValueType::intValue}, {\"p2\", Json::ValueType::stringValue}});\n\n   // here we set the callback for any json call\n    rpc.setResponseCallback([](std::string\u0026\u0026 res) {\n        // res has the json response of the server\n    });\n\n    // post is synchronous, and asyncPost is asynchronous\n    rpc.post(\n        R\"({\"jsonrpc\": \"2.0\", \"method\": \"testmethod1\", \"params\": {\"p1\": 5, \"p2\": \"HiThere!!!\"},\n                \"id\": 4})\",\n        \"TheString\");\n```\n\n# Dependencies\nAsyncJsonRPC depends on two libraries:\n1. libjsoncpp\n2. boost containers\n\n**libjsoncpp** is required for json parsing. That cannot be changed.\n\n**Boost** is necessary just for a [`flat_map`](https://www.boost.org/doc/libs/1_65_1/doc/html/boost/container/flat_map.html), which I used instead of `std::map`. This is done purely for performance. A `flat_map` uses a vector underneath, which guarantees cache locality and makes look-ups very fast. A hash-map isn't very suitable if performance is to be sought, because hashing strings isn't that fast. With a `flat_map`, for this specific problem where methods will be added once and will never be changed later.\n\n**But I don't want boost!** in that case, just change the type from `flat_map` to `std::map` if performance isn't a big deal for you.\n\n**Conan as a dependency manager**: Conan retrieves boost for you and compiles it automatically for you. It's not necessary if you want to use your system version of boost. Feel free to change the `CMakeLists.txt` file and remove conan.\n\n### Thread-safety\nThread-safety is meant to be satisfied during operation. The only thread-safe methods are `AsyncJsonRPC::post()` and `AsyncJsonRPC::asyncPost()`. Anything else is **not thread-safe**, by design! Either that, all I'll have to stack mutexes all over the place. I'm sure you don't want that :-)\n\nSo, it's expected that you define your methods, handlers, callback in the main-thread, then start with the heavy-load stuff.\n\n### Thread, memory, undefined behavior and other safety checks\n\nFor quality assurance, you can build the project with clang-sanitizers enable. Please enable one only at a time. The following are the CMake options to enable:\n\n- `SANITIZE_THREAD`\n- `SANITIZE_UNDEFINED`\n- `SANITIZE_ADDRESS`\n- `SANITIZE_LEAK`\n\nFor example, run cmake with `-DSANITIZE_LEAK=ON` to enable leak sanitizer.\n\n### Building\nYou **do not** need to build this library to use it. Just include `#include \"asyncjsonrpc/AsyncJsonRPC.h\"` and it'll work. It's header only.\n\nYou may, however, build the tests! Feel free to build and run them. The `CMakeLists.txt` file in the root directory does that for you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthequantumphysicist%2Fasyncjsonrpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthequantumphysicist%2Fasyncjsonrpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthequantumphysicist%2Fasyncjsonrpc/lists"}