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

发布时间:2026/11/7 12:58:57

用 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),仅供参考
延伸阅读

更多相关文章

2026/10/24 9:05:36

2009年408链表算法题详解:双指针查找倒数第k个节点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 14:44:07

containerd 插件体系完全指南:从代理插件到内置插件

containerd 插件体系完全指南:从代理插件到内置插件 【免费下载链接】containerd An open and reliable container runtime 项目地址: https://gitcode.com/GitHub_Trending/co/containerd 本篇技术指南以 containerd 官方文档 docs/PLUGINS.md 为核心骨架&a…

2026/11/7 12:54:18

特种工退休需哪些手续多少钱才够用

特种工退休需哪些手续多少钱才够用 不知道去哪报名怕被中介坑?特种工退休手续复杂,手续费用也让人摸不着头脑。别急,下面这些信息帮你把关,从报名到退休手续,每一步都讲得明明白白,避免你被“黑中介”坑了钱还办不好事。…

2026/11/7 12:54:18

天门低压电工证培训通过率揭秘:如何避免交了钱还考不过

天门低压电工证培训通过率揭秘:如何避免交了钱还考不过 怕考不过白交培训费?别再盲目报名了,天门低压电工证培训的通过率揭秘,能帮你避开那些坑,省下冤枉钱。很多人报班后,不仅没拿到证,还浪费了时间、金钱和精力。其实,只要选对培训机构、掌握正确备…

2026/11/7 12:54:18

宜章电工证报名地址值不值得考?工地太忙根本没时间复习考试

宜章电工证报名地址值不值得考?工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这几乎是每个特种作业人员的真实写照。尤其是像你这样刚毕业的洛阳工程类学生,面对繁重的工作任务,还得抽空准备电工证考试,压力实在不小。但…

2026/11/7 12:54:18

漳州电工证要重新考保姆级教程:外省证怎么转?全流程避坑指南

漳州电工证要重新考保姆级教程:外省证怎么转?全流程避坑指南 之前考的证在外省能不能转过来?这是很多从外地来漳州打工的电工最关心的问题。今天就以一个真实案例为线索,带大家一步步搞清楚【漳州电工证要重新考】背后的流程、要求和避坑点,尤其是那些跨…

2026/11/7 12:54:18

天门低压电工证培训怎么转到河南?2026河南最新政策全解析

天门低压电工证培训怎么转到河南?2026河南最新政策全解析 之前考的证在外省能不能转过来?这几乎是每个准备在河南发展的电工都会问的问题。2026年河南最新政策出台后,关于天门低压电工证培训与证书转接的问题,有了更清晰的答案。如果你是在洛阳涧…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/6 10:49:01

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑