GitHub - nnevatie/capnwebcpp: Cap'n Web C++

3 min read Original article ↗

capnwebcpp

CI (Linux • macOS • Windows) Interop (Node ↔ capnweb)

Cap'n Web C++ library. Build Cap'n Web RPC services in C++ with uWebSockets/WebSocket, HTTP batch, and MessagePort transports, robust serialization and lifecycle handling, plus a minimal C++ client (HTTP batch and WebSocket) for calling Cap'n Web endpoints.

Status

Server-focused implementation of the Cap'n Web RPC protocol with bidirectional calling support.

capnwebcpp provides WebSocket and HTTP-batch transports plus a MessagePort adapter, implements remap and a client-call path for server→client calls, and includes serialization hardening and robust lifecycle handling. A minimal C++ HTTP batch client and a uWebSockets-based WebSocket client are available; the library interoperates with the original TypeScript/JavaScript capnweb client.

Area Status
Core protocol (push/pull/resolve/reject/release/abort)
Serialization + hardening
Remap / pipelining
Transports (WebSocket, HTTP batch, MessagePort)
Server→client calls
Import/export tables + refcounts
Lifecycle (abort, drain, stats)
C++ client (HTTP batch + WebSocket) ⚠️
Interop & tests

Status icons: ✅ implemented, ⚠️ partial, ❌ not yet implemented

Ongoing Work

  • Diagnostics/logging: richer stats, tracing hooks
  • C++ client: async API, stub lifecycle/release, promise awaiting/pipelining, wss/TLS, reconnection
  • Additional adapters: Workers/Node helpers and transports
  • Interop: broader coverage and fuzz tests against capnweb
  • Performance: microtask scheduling, caching, event-loop integration
  • Docs: client usage (batch/WS), wss setup, batch caveats, server→client examples

Dependencies

Building (with Ninja)

git clone https://github.com/nnevatie/capnwebcpp.git
cd capnwebcpp
mkdir build
cd build
cmake -G Ninja ..
ninja

Running Examples

Helloworld

examples\helloworld\helloworld ..

Open a helloworld client in a browser.

Batch-pipelining

examples\batch-pipelining\batch-pipelining ..

Open a batch-pipelining in a browser.

MessagePort (in-process)

examples\\messageport\\messageport ..

This example uses an in-process MessageChannel to simulate client/server over a MessagePort transport.

WebSocket Callback (server→client calls)

examples\\websocket-callback\\websocket-callback ..

Open a WebSocket callback client in a browser. The server calls back to the client’s RPC target using the server→client call API.

C++ Client (HTTP Batch)

Use the minimal batch client to call a remote server from C++. Provide a transport function that takes outbound frames and returns the server’s responses.

Example:

#include <capnwebcpp/client_api.h>

using namespace capnwebcpp;

// Implement this to POST batch.join("\n") to your server and split("\n") the response.
std::vector<std::string> sendBatch(const std::vector<std::string>& batch);

int main() {
    auto transport = std::make_shared<FuncBatchTransport>(sendBatch);
    RpcClient client(transport);
    auto result = client.callMethod("hello", nlohmann::json::array({"World"}));
    // result == "Hello, World!"
}

Stub results can be called using callStubMethod() / getStubProperty() with the returned { "$stub": id }.

C++ Client (WebSocket, persistent)

Use the uWebSockets-based persistent client to keep a WebSocket open and issue multiple calls:

#include <capnwebcpp/client_ws.h>

using namespace capnwebcpp;

int main() {
    RpcWsClient client("ws://127.0.0.1:8000/api");
    auto res = client.callMethod("hello", nlohmann::json::array({"World"}));
    // res == "Hello, World!"
}

Note: Current client is synchronous and sends a release after each resolve. Advanced features (promise awaiting, batched pipelining, bidirectional callbacks) are limited and will be expanded.