资讯详情

资讯详情

用 C++ 构建 SpacetimeDB 模块:连接/断开事件的 sdk-test-connect-disconnect-cpp 实战剖析

用 C 构建 SpacetimeDB 模块连接/断开事件的 sdk-test-connect-disconnect-cpp 实战剖析【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB本文基于 SpacetimeDB 仓库中的 modules/sdk-test-connect-disconnect-cpp/README.md 及其源码讲解如何用 C 编写一个专门用于观测 WebSocket 客户端连接connect与断开disconnect生命周期事件的测试模块。你将掌握 C SDK 中SPACETIMEDB_CLIENT_CONNECTED/SPACETIMEDB_CLIENT_DISCONNECTED生命周期回调的写法、表与 reducer 的声明方式以及如何通过 Emscripten CMake 将模块编译为lib.wasm并交给 SDK 测试框架验证。一、模块定位C 版的连接生命周期观测器sdk-test-connect-disconnect-cpp是 SpacetimeDB 仓库modules/目录下的一个 C 测试模块。它的职责非常聚焦验证 C 绑定bindings-cpp能否正确观测到 WebSocket 客户端的连接与断开事件。该模块刻意保持最小化——只有一张Connected表、一张Disconnected表以及两个生命周期 reducer没有多余的初始化逻辑这让它成为理解 C 模块生命周期回调的最佳入门样本。它的设计直接镜像了同名 Rust 模块 modules/sdk-test-connect-disconnect/src/lib.rs 与 C# 模块 modules/sdk-test-connect-disconnect-cs/Lib.cs目的是在多个语言 SDK 之间保持功能对齐feature parity。三个语言版本的逻辑一一对应语言模块文件Connected/Disconnected 表生命周期 reducerRustmodules/sdk-test-connect-disconnect/src/lib.rs#[table(accessor connected, public)]等#[reducer(client_connected)]等C#modules/sdk-test-connect-disconnect-cs/Lib.cs[SpacetimeDB.Table(Accessor connected, Public true)]等[SpacetimeDB.Reducer(ReducerKind.ClientConnected)]等Cmodules/sdk-test-connect-disconnect-cpp/src/lib.cppSPACETIMEDB_TABLE(Connected, connected, Public)等SPACETIMEDB_CLIENT_CONNECTED(...)等从源码结构看这种多语言镜像策略是 SpacetimeDB 在 crates/bindings-cpp 与 crates/bindings、crates/bindings-csharp 等多套绑定之间保证行为一致的重要手段同一套测试语义用三种语言各实现一遍任何一端的回归都会被对应测试暴露。二、源码全貌完整的lib.cppC 模块的全部逻辑集中在 modules/sdk-test-connect-disconnect-cpp/src/lib.cpp全文仅 30 余行结构非常清晰#include spacetimedb.h #include optional #include vector #include cmath using namespace SpacetimeDB; // Tables matching Rust sdk-test-connect-disconnect struct Connected { Identity identity; }; SPACETIMEDB_STRUCT(Connected, identity) SPACETIMEDB_TABLE(Connected, connected, Public) struct Disconnected { Identity identity; }; SPACETIMEDB_STRUCT(Disconnected, identity) SPACETIMEDB_TABLE(Disconnected, disconnected, Public) // Reducers: client lifecycle callbacks SPACETIMEDB_CLIENT_CONNECTED(identity_connected, ReducerContext ctx) { ctx.db[connected].insert(Connected{ ctx.sender() }); return Ok(); } SPACETIMEDB_CLIENT_DISCONNECTED(identity_disconnected, ReducerContext ctx) { ctx.db[disconnected].insert(Disconnected{ ctx.sender() }); return Ok(); }2.1 表声明结构体 三个宏每个表由三行组成普通 C 结构体struct Connected { Identity identity; }定义行字段。这里的Identity是 C 绑定提供的类型来自 crates/bindings-cpp/include表示客户端唯一身份标识。SPACETIMEDB_STRUCT(Connected, identity)将该结构体注册为 SpacetimeDB 的可序列化数据类型第二个参数列出参与序列化的字段名。SPACETIMEDB_TABLE(Connected, connected, Public)将其注册为模块表。第二个参数connected是表访问器名类似 Rust 侧#[table(accessor connected)]第三个参数Public控制表的可见性——Public 表示客户端可以订阅该表。SpacetimeDB 的 C 绑定crates/bindings-cpp/src会基于这些宏在编译期生成表的插入、查找、索引、订阅等底层机制。2.2 生命周期回调两个关键宏SPACETIMEDB_CLIENT_CONNECTED(identity_connected, ReducerContext ctx)当客户端通过 WebSocket 建立连接时触发。宏的第一个参数是 reducer 名称对应 Rust 的client_connected事件名第二个参数是上下文类型。回调体内用ctx.db[connected].insert(Connected{ ctx.sender() })把当前连接者的Identity写入connected表。SPACETIMEDB_CLIENT_DISCONNECTED(identity_disconnected, ReducerContext ctx)当客户端断开连接时触发把断开者的Identity写入disconnected表。对比 Rust 版本modules/sdk-test-connect-disconnect/src/lib.rs语义完全一致Rust 侧用#[spacetimedb::reducer(client_connected)]和ctx.db.connected().insert(Connected { identity: ctx.sender() })C 侧的ctx.sender()、ctx.db[connected]、.insert(...)与 Rust 的ctx.sender()、ctx.db.connected()、.insert(...)一一对应体现了 C 绑定在 API 形态上对 Rust 绑定的刻意对齐。2.3 测试流程设计从 Rust 模块的文档注释modules/sdk-test-connect-disconnect/src/lib.rs可以还原出完整的测试流程客户端连接一次客户端订阅Connected表观察表中出现一行其Identity与当前客户端一致客户端断开后再次重连客户端订阅Disconnected表观察表中出现一行其Identity与当前客户端一致。也就是说connected表记录来过的客户端disconnected表记录离开的客户端。测试断言的核心是生命周期回调确实被调用且ctx.sender()返回的身份信息正确。三、构建Emscripten CMake 产出lib.wasmREADME 给出了两条构建命令emcmake cmake -B build cmake --build build输出产物为build/lib.wasm。这意味着该 C 模块以WebAssembly 模块的形式运行在 SpacetimeDB 主机上类似 Rust 模块经cargo build --target wasm32-wasi产出的 wasm。构建细节由 modules/sdk-test-connect-disconnect-cpp/CMakeLists.txt 定义值得关注的要点如下模块源文件与输出名默认MODULE_SOURCE为src/lib.cppOUTPUT_NAME为lib均允许通过 CMake 变量覆盖依赖的 C 绑定SPACETIMEDB_CPP_LIBRARY_PATH指向仓库内的 crates/bindings-cpp通过add_subdirectory引入并链接spacetimedb_cpp_libraryWASM 编译选项-fno-exceptions -O2 -g0并设置CMAKE_CXX_STANDARD 20导出函数列表导出_malloc、_free、___describe_module__、___call_reducer__、___call_view__、___call_view_anon__等其中___call_reducer__就是主机调用 reducer包括生命周期回调的统一入口独立 WASM 产物-sSTANDALONE_WASM1、--no-entry、-sWASM1生成无 JS 胶水层的纯.wasm体积与正确性权衡-sFILESYSTEM0裁剪运行时、-sINITIAL_MEMORY16MB固定初始内存、-sALLOW_MEMORY_GROWTH0禁止内存增长、-sERROR_ON_UNDEFINED_SYMBOLS1保证链接期符号完整性产物命名通过set_target_properties(lib PROPERTIES OUTPUT_NAME lib SUFFIX .wasm)保证输出为build/lib.wasm。四、如何运行测试该模块的测试并不单独运行而是由 SpacetimeDB Rust SDK 的集成测试统一驱动。Rust 侧的测试入口在 sdks/rust/tests/test.rs运行命令详见 modules/sdk-test-connect-disconnect/README.md# Will run both Rust/C# modules cargo test -p spacetimedb-sdk connect-p spacetimedb-sdk指定测试所在的 crateconnect是测试名过滤器用于只跑与连接生命周期相关的用例。测试会启动一个本地 SpacetimeDB 实例加载对应的测试模块Rust / C# 版本然后由测试客户端按上文第 2.3 节的流程执行连接、订阅、断开、重连并断言结果。C 版本遵循同一套测试语义因此只要把构建出的lib.wasm作为模块载入即可用同样的断言思路验证 C 绑定的事件回调是否按预期触发。五、小结与延伸阅读modules/sdk-test-connect-disconnect-cpp是一个教科书级的 C SpacetimeDB 模块样本两个表、两个生命周期 reducer、三行构建命令却完整覆盖了客户端生命周期事件可被观测这一核心能力并与 Rust、C# 版本保持严格对齐。如果你想继续深入对比 C# 实现 modules/sdk-test-connect-disconnect-cs/Lib.cs可以看到同一语义在不同绑定下的写法差异查看 Rust 实现的 modules/sdk-test-connect-disconnect/src/lib.rs 了解client_connected/client_disconnected事件的声明方式阅读 crates/bindings-cpp/ARCHITECTURE.md 与 crates/bindings-cpp/REFERENCE.md了解SPACETIMEDB_CLIENT_CONNECTED等宏背后的绑定架构与完整 API 参考。【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →