开发与设备接入
Keragi 不限于现有客户端:服务端可以加载自定义 WASM 资源,设备也可以通过网关或客户端身份接入消息系统。本页给出接口模型、简单示例与设备接入方式。
1. 两种扩展方式
- 自定义 WASM 资源:运行在 wasmx 宿主内,注册 HTTP / SSE / WebSocket 路由,使用宿主提供的数据库、时钟、对象存储等能力。适合设备网关、协议转换、自动化与内部工具。
- 设备接入:设备本身不运行 wasmx 宿主(宿主目前只支持 Linux x86_64)。设备通过 HTTP、MQTT、串口等协议连接到自定义网关资源,或作为客户端参与者加入会话。
2. 自定义 WASM 资源
2.1 运行模型
- 资源编译为
wasm32-unknown-unknown的cdylib,由宿主从wasmx.json加载,并按prefix挂载路由。 - 资源内不直接做文件、网络或线程 I/O;数据库、时钟、对象存储等通过宿主函数完成。
- 支持普通 HTTP handler,以及 SSE、WebSocket、上传等数据面。
- 资源可以使用独立的 SQLite 数据库,并按需接入
userx的认证与权限。
2.2 简单案例:hello + echo
下面是一个最小资源,提供 GET /demo/hello 与 POST /demo/echo。
Cargo.toml:
[package]
name = "hello-resource"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[features]
default = ["wasm"]
wasm = ["wasm-core/wasm"]
[dependencies]
wasm-core = { version = "0.1", default-features = false }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
src/lib.rs:
use serde::{Deserialize, Serialize};
use wasm_core::{get, post, wasm_handler, wasm_main, Json, Router};
#[wasm_main]
fn router() -> Router {
Router::new()
.route("/hello", get(hello))
.route("/echo", post(echo))
}
#[wasm_handler]
async fn hello() -> String {
"hello from hello-resource".to_string()
}
#[derive(Deserialize)]
struct EchoRequest {
message: String,
}
#[derive(Serialize)]
struct EchoResponse {
message: String,
}
#[wasm_handler]
async fn echo(Json(req): Json<EchoRequest>) -> EchoResponse {
EchoResponse { message: req.message }
}
构建:
cargo build --release --target wasm32-unknown-unknown \
--no-default-features --features wasm
产物为 target/wasm32-unknown-unknown/release/hello_resource.wasm。
2.3 打包与安装
资源目录:
hello-resource/
├── package.json
├── wasmx.resource.json
└── wasm/hello.wasm
package.json:
{
"name": "@example/hello-resource",
"version": "0.1.0",
"files": ["wasm", "wasmx.resource.json"]
}
wasmx.resource.json:
{
"resources": [
{
"name": "hello",
"file": "hello.wasm",
"config": { "prefix": "/demo", "allow_http": true }
}
]
}
安装并启动:
cp target/wasm32-unknown-unknown/release/hello_resource.wasm \
hello-resource/wasm/hello.wasm
wasmx add ./hello-resource
wasmx stop
wasmx start
curl http://127.0.0.1:3001/demo/hello
curl -X POST http://127.0.0.1:3001/demo/echo \
-H 'content-type: application/json' \
-d '{"message":"hi"}'
示例使用当前 Rust SDK 的接口形态。官方 SDK、宏、模板与示例的对外获取方式将在开发者版本中公布;接口如有调整,以对应版本的 SDK 文档为准。
2.4 数据与鉴权
- 数据库:通过 SDK 的
db()使用宿主注入的数据库连接;建表 SQL 随资源声明,由宿主在加载时执行。 - 鉴权:需要登录态的资源应校验
userx签发的令牌,并按 scope 限制接口。 - 敏感配置:放在宿主或资源专属的
.env,不要写进代码或镜像。 - 版本兼容:资源与宿主版本需要匹配;升级宿主后应重新验证资源。
3. 设备接入
3.1 三种接入模式
| 模式 | 数据路径 | 能否读取端到端加密消息 | 适用场景 |
|---|---|---|---|
| 设备作为客户端参与者 | 设备持有独立身份与密钥,加入指定会话/频道 | 能,但仅限其作为成员可解密的会话 | 有安全存储与一定算力的设备 |
| WASM 网关资源 | 设备 ↔ 网关资源 ↔ 消息系统 | 不能解密端到端加密消息;只能处理明文/机器人通道或由客户端桥接 | 传感器、执行器、HTTP/MQTT 设备 |
| 本地边缘桥接 | 设备 ↔ 本地桥接程序(客户端)↔ 会话 | 能,桥接机成为可信端点 | 家庭、工业现场、串口/GPIO 设备 |
加密边界:服务端只持有密文,运行在服务端的 WASM 网关无法解密端到端加密消息。需要读取加密消息的设备,必须以客户端参与者身份加入,或通过本地桥接在客户端侧解密后再控制设备。
3.2 典型数据流
- 传感器上报:设备
POST /device/{id}/telemetry→ 网关资源写入消息/频道 → 客户端、机器人与告警系统消费。 - 命令下发:客户端发送命令消息 → 本地桥接(客户端)解密 → MQTT / 串口 → 继电器或执行器。
- 网关订阅:网关资源订阅明文/机器人通道或接收 webhook → 调用设备 HTTP/MQTT 接口执行动作。
3.3 示例接口
以下是网关资源可以实现的一组接口,具体协议由设备侧决定:
| 方法 | 路径 | 用途 |
|---|---|---|
POST | /device/{id}/telemetry | 上报传感器数据,例如 {"temperature":23.5,"ts":...} |
GET | /device/{id}/commands | SSE/WebSocket 长连接,接收命令 |
POST | /device/{id}/ack | 确认命令执行结果 |
POST | /device/{id}/relay | 控制继电器/执行器,例如 {"channel":1,"on":true} |
GET | /device/{id}/state | 查询设备状态 |
3.4 认证与安全
- 每台设备使用独立设备 ID 与凭据;不要复用管理员账号。
- 所有控制接口必须鉴权,并按设备/用户/操作粒度授权。
- 设置限流、超时与幂等键,避免重复下发和风暴。
- 设备凭据存放在安全存储中;支持轮换,避免明文写入固件或日志。
- 网关与设备之间建议使用 TLS 或处于受控网络;不要把管理接口直接暴露到公网。
- 记录命令下发、执行与失败日志,便于审计与排障。
3.5 执行器与物理安全
重要:继电器、电机、阀门等执行器涉及人身与财产安全。必须设计失效安全(fail-safe)、急停、超时复位、权限校验与人工接管,并在真实负载前完成测试。本文示例仅用于说明软件接入方式,不构成工业安全认证或安全保证。
3.6 ESP32 等设备
- wasmx 宿主目前只支持 Linux x86_64,不运行在 ESP32 等 MCU 上。
- ESP32 等设备可以通过 HTTP/MQTT 连接网关资源,或在资源允许的前提下作为轻量客户端参与者。
- 设备端的协议、固件与安全存储由接入方负责;服务端只提供消息与资源能力。