Skip to content

WebSocketManager Controller (NativeAOT Worker)

A WorkManager worker compiled with NativeAOT for the NativeDllEngine, mirroring the DotNet DLL WebSocketManager controller. The worker is loaded as a native shared library (.so/.dylib/.dll) and runs in-process with WorkManager, eliminating JIT startup cost.

Topic: command.websocketmanagercontroller Group: websocketmanagercontroller MIME type: application/x-nativedll

Architecture

Command Event (CloudEvent on command.websocketmanagercontroller)
Dapr Pubsub → WorkManager → NativeDllEngine → [UnmanagedCallersOnly] Process
AotNativeWorkerBase.ProcessStatic<T> → AotNative<W>.ProcessStatic (FlatBuffer decode, dispatch)
WebSocketManagerControllerNative.HandleAsync
NativeApiGateway.InvokeAsync("websocketmanager", method, jsonBytes)
host->gateway_call (C ABI host callback into WSM gRPC client)
Returns response CloudEvent (topic: response.websocketmanagercontroller)

Building

cd dotnet
bash scripts/build_websocket_manager_controller.nativeaot.sh

The build script: 1. Calls dotnet publish -c Release -r <rid> with PublishAot=true and IsAotCompatible=true. 2. Packages the resulting libcontroller.<so|dylib|dll> into worker.zip:

worker.zip/
├── manifest.json
└── runtimes/<rid>/native/libcontroller.<so|dylib|dll>

The manifest.json declares abi_version: 1 and library: "controller".

Running

WORKER_B64=$(base64 -i bin/nativeaot/worker.zip | tr -d '\n')
curl -X POST http://localhost:25001/v1/workers \
  -H "Content-Type: application/json" \
  -d "{
    \"code_source\": {\"content\": \"$WORKER_B64\"},
    \"mime_type\": \"application/x-nativedll\",
    \"topic\": \"command.websocketmanagercontroller\",
    \"group\": \"websocketmanagercontroller\"
  }" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])" | xargs -I{} curl -X POST http://localhost:25001/v1/workers/{}/start

Key Differences from the DotNet DLL Version

Aspect DotNet DLL (in-process) NativeAOT
Engine DotNetDllEngine (in-process, JIT) NativeDllEngine (in-process, AOT)
Compiled by dotnet publish dotnet publish -p:PublishAot=true
Binary extension .dll .so / .dylib / .dll
Gateway calls ApiClient.InvokeAsync (managed gRPC) NativeApiGateway.InvokeAsync (C ABI host callback)
Base class ApiCommandWorker<T> CommandWorker<T> (same; only the bridge differs)
Worker exports IWorker.ProcessAsync (JIT reflection) [UnmanagedCallersOnly] Process + FreeResult
Startup ~500 ms (JIT load) <10 ms (dlopen only)

Commands

Identical to the Out-of-process DotNet DLL version — see websocketmanagercontroller.md.

See Also