@crvouga/mockingbird-service-aws-iot

中文文档
0.10.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 3002

AWS IoT Core Data平面的状态仿真器:由SigV4签名的HTTP Publishing和由TCP和WebSocket负责的MQTT 5消息经纪人,有自定义授权政策和持续会话.

中文使用文档
文档目录9 节
  1. 安装
  2. 使用量
  3. 路线
  4. MQTT 数据
  5. 管理员(超过标准合同)
  6. 命名空间
  7. 未核实
  8. 故意不模拟
  9. API 密码

@crvouga/mockingbird-service-aws-iot (英语)

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

国家模拟器 AWS IOT 核心数据平面 测试套房和地方开发: IoTData 计划 Publish hTTP 有签名版本 4 验证和 MQTT 5 信件 tCP和WebSocket的经纪人(/mqtt)与自定义授权政策,AWS IoT的持久性 课程规则及其与 MQTT 规格的偏离。 它在测试中运行 在没有 AWS 账户的 OS 指定端口上进行处理,会话到期会跟随套件的时钟 移动而不是等待.

  • 行动覆盖( HTTP): 支助
  • 没有AWS账户被用作甲骨文. 行为遵循 发布 API 引用, (中文(简体) ), 页:1 MQTT 数据, (中文(简体) ), 自定义认证, (中文(简体) ), 政策 财务报告和审定财务报表 配额 页面,以及AWS的SDK标志. 未结算的列在下面 未核实。 。 。 .
  • 这不是EM Q的模仿者 与另一个名字: (单位:千美元)@crvouga/mockingbird-service-emqx)),各随自取.

安装

npm install -D @crvouga/mockingbird-service-aws-iot

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 npx mockingbird-aws-iot serve 或者说 createServer 从 ./server (节点和邦). createRuntime (默认条目)是可移植的:服务 Publish 结束 fetch 和 MQTT 通过 runtime.attach没有听者.

使用量

将应用程序的 IOT 数据端点指向 url 及其在 mqttUrl 或者说 wsUrl没有 TLS: 使用 http://, (中文(简体) ), mqtt:// 财务报告和审定财务报表 ws:// 给定的 URL .

import { createServer } from "@crvouga/mockingbird-service-aws-iot/server"
import { IoTDataPlaneClient, PublishCommand } from "@aws-sdk/client-iot-data-plane"
import mqtt from "mqtt"

// Test setup: start the emulator with the credentials and authorizer policies the test needs.
const arn = (resource: string) => `arn:aws:iot:us-east-1:123456789012:${resource}`
const iot = await createServer({
  settings: {
    // HTTP: SigV4 signatures are verified against these keys.
    credentials: [{ accessKeyId: "test-key", secretAccessKey: "test-secret" }],
    // MQTT: what the custom authorizer answers for a username and password.
    authorizers: [
      {
        username: "alice",
        password: "alice-token",
        policyDocuments: [
          {
            Version: "2012-10-17",
            Statement: [
              { Effect: "Allow", Action: "iot:Connect", Resource: arn("client/alice-*") },
              { Effect: "Allow", Action: "iot:Subscribe", Resource: arn("topicfilter/user/alice") },
              { Effect: "Allow", Action: "iot:Receive", Resource: arn("topic/user/alice") },
            ],
          },
        ],
      },
    ],
  },
})

// Application code: the MQTT client and AWS SDK client it already uses, pointed at the emulator.
const device = await mqtt.connectAsync(iot.mqttUrl, {
  protocolVersion: 5,
  clientId: "alice-phone",
  clean: false,
  properties: { sessionExpiryInterval: 600 },
  username: "alice",
  password: "alice-token",
})
await device.subscribeAsync("user/alice", { qos: 1 })

const client = new IoTDataPlaneClient({
  region: "us-east-1",
  endpoint: iot.url,
  credentials: { accessKeyId: "test-key", secretAccessKey: "test-secret" },
})
await client.send(new PublishCommand({ topic: "user/alice", qos: 1, payload: '{"hello":"alice"}' }))

await device.endAsync()
await iot.close() // closes every listener and drops every client
npx mockingbird-aws-iot serve --port 8851 --mqtt-port 8883 \
  --credential test-key:test-secret --settings ./aws-iot-settings.json

每个 createServer() 是它自己拥有自己的港口的经纪人,其中两个没有分享任何东西。 下 邦顿, mqtt节点 WebSocket 传输没有启动( Bun) ws 没有 createWebSocketStream,所以连接到 wsUrl 与库的浏览器传输 (单位:千美元)new MqttClient((c) => browserStreamBuilder(c, options), options) 从 mqtt/lib/connect/ws, (中文(简体) ), 或用途 connectStream(runtime) 从 ./server 用于无套接字连接。 在平原的节点上 mqtt.connect("ws://…/mqtt") 工作时.

话题是客户发送的。 AWS IOT 与 / 并给出 : 没有意义, 因此,一个名为主题的应用程序 user:example 并公布为 user/example 这样做 映射本身;模拟器像AWS一样,从未看到第一个形式.

路线

路线行为
POST /topics/{topic}?qos=0|1IoTData 计划 Publish身体是有效载荷,作为发送的字节。 话题为 %- 解码一次( Q)user%2Fexample 实值 user/example· ; a%252Fb 字义 a%2Fb);未编码的鞭打也被接受,如AWS本身的例子. 200 {"message": "OK", "traceId": "…"} 无论是否有人订阅。 另见: retain, (中文(简体) ), contentType, (中文(简体) ), responseTopic, (中文(简体) ), messageExpiry (调整为1-60480) x-amz-mqtt5-user-properties, (中文(简体) ), x-amz-mqtt5-payload-format-indicator 财务报告和审定财务报表 x-amz-mqtt5-correlation-data 信头, 以 MQTT 5 属性覆盖订阅者 .
错误{"message": "…", "traceId": "…"} 与 x-amzn-ErrorType。 。 。 . 400 InvalidRequestException 对于一个已空出、有通配符、超过256字节或7下划线或从 $页:1 qos 0或1以外; 错误 retain, (中文(简体) ), messageExpiry 或 MQTT 5 头; 畸形% 逃出; 有效载荷超过 128 KB. 401 UnauthorizedException 当签名身份政策不允许时 iot:Publish 关于这个话题. 403 (单位:千美元)Forbidden请求未经签字或其签字未核实. 405 MethodNotAllowedException 对于任何其他动词或路径。 一个 x-mockingbird-reason 信头显示检查失败 .

SigV4 (英语). 与 credentials 空的, 任何包含一个完整格式的请求 Authorization: AWS4-HMAC-SHA256 … 信头不被验证(作为Mockingbird的另一个AWS) 模拟者也这样做),未签名的请求仍然被拒绝. 已配置了证书 签名必须验证:服务 iotdata,配置的区域, host 财务报告和审定财务报表 x-amz-date 签名, 路径在犬科请求中编码了第二次(除了S3之外的所有服务),有效载荷 将身体的SHA -256,和 x-amz-security-token 匹配临时证书. 证书的 policyDocuments当给定时,必须允许 iot:Publish 打开 arn:aws:iot:<region>:<account>:topic/<topic>。 。 。 .

MQTT 数据

MQTT 5.0 在TCP和WebSocket上运行 /mqtt (副议定书) mqtt) (中文(简体) ). 都一样 各届会议和同一届会议 Publish 送货给.

区域行为
认证只自定义认证 . authorizers 使用 MQTT 用户名和密码( 用户名) 列出自定义授权者的结果 ?x-amz-customauthorizer-name=… 查询读取或删除;或 通过 authorizer 改为 createRuntime,接收 Lambda 事件的函数(protocolData.mqtt.{username, password (base64), clientId}返回时 {isAuthenticated, principalId, policyDocuments}。没有匹配条目, isAuthenticated: false,或不允许 iot:Connect 打开 client/<clientId> 关闭 0x87。由于既没有配置每个客户端的连接,所以允许一切.
政策iot:Connect 打开 client/<id>, (中文(简体) ), iot:Publish 财务报告和审定财务报表 iot:Receive 打开 topic/<name>, (中文(简体) ), iot:Subscribe 打开 topicfilter/<filter>默认拒绝; 明示 Deny 覆盖任意 Allow。 。 。 . * 财务报告和审定财务报表 ? 为通配符( e)* ; MQTT 级别 + 财务报告和审定财务报表 # 在策略中是普通字符,所以策略必须给客户端订阅的过滤器命名. ${iot:ClientId} 扩张。 一个否认的子公司是SUBACK 0x87; 被拒绝的Qos 1 PUBLISH 是 PUBACK 0x87; 无 iot:Receive 对于一个话题,默默地从它没有得到任何东西.
结束最大QoS 1, 保留可用 0 (见下文), 最大包大小 149504, Topy Alias 最大 8, 接受最大 100, Wildcard 订阅 可用 1, 订阅标识 可用 0, 共享订阅 可用 0. 服务器在 AWS 更改客户端时保持存活 : 1200 for 0 或超过1200人,30人不满30人.
常年会议Clean Start 0,会话间隔超过 0 。 间隔以账户配额为上限(persistentSessionExpirySeconds,默认1小时,最多7天),调整后的价值在CONNACK中返回. 一个会话只保留其订阅和QoS 1消息(QoS 0没有被存储). 连接结束时开始计时器; 到期时会话及其队列被丢弃 .
客户端 ID最多128个字节( CONNACK) 0x85 页:1 接受与连接客户端 ID 的第二个连接,并发送第一个 DICONNECT 0x8E。 。 。 .
专题最多 256 字节和 7 前向斜线; 话题和过滤器开始 $ 被拒绝(SUBACK) 0x8F胶片 0x90) (中文(简体) ). sensor/# 匹配 sensor/ 财务报告和审定财务报表 sensor/a/b 没有 sensor。 。 。 .
基辅语Name0和1. 要求QoS 2的子公司得不到分包;QoS 2 PUBLISH被回答 0x9B。没有人订阅的刊物会被确认 0x00。 。 。 .
有效载荷最多128 KB;一个更大的PUBLISH断开客户端.
订阅标识符不支持,如关于AWS:DICONNECT 0xA1。 。 。 .

管理员(超过标准合同)

路线效果
GET /__admin/publishes{total, publishes}: 接受的最后1000种出版物为元数据(topic, (中文(简体) ), qos, (中文(简体) ), bytes, (中文(简体) ), source: "http" | "mqtt" | "admin", (中文(简体) ), clientId, (中文(简体) ), matched, (中文(简体) ), at) (中文(简体) ). 有效载荷从不保存.
GET /__admin/clients, (中文(简体) ), GET /__admin/clients/:clientId会话 : connected, (中文(简体) ), transport, (中文(简体) ), sessionExpiryInterval, (中文(简体) ), expiresAt,计数 subscriptions, (中文(简体) ), queued, (中文(简体) ), inflight; 其中一会还列出其 topics。 。 。 .
GET /__admin/subscriptions?clientId=订阅: topicFilter,准予 qos,选项.
POST /__admin/inject{topic, payload | payloadBase64, qos?: 0 | 1}:向该话题的订阅者提供生字节,绕过签名,验证并发布政策(iot:Receive 页:1 用它来表示一个消费者的解析器必须拒绝。 答复 {matched}。 。 。 .
POST /__admin/transport/cut{clientId?}:一个客户端或所有客户端的网络断电. 现场连接因没有DICONNECT而死亡,新的CONNECT被放弃,没有得到答复. 会话未受影响,按自己的时间安排过期.
POST /__admin/transport/restore{clientId?}:结束停产. GET /__admin/transport 列出切出的内容.
POST /__admin/clients/:clientId/disconnect{reasonCode?}: 发送 DICONNECT( 默认) 0x98)和结束;会议将停止.
GET 编号 : PUT /__admin/settings{credentials?, authorizers?, region?, accountId?, persistentSessionExpirySeconds?} 呼叫的命名空间。 无法评估的仿真文件被拒绝使用 400重置运行时间创建的值的返回.
POST /__admin/clock标准 移动时钟解决会话即时失效.
POST /__admin/reset检查站标准 重置会降低每个连接和会话 。 恢复检查点会恢复会话,订阅和队列,并会减少直播连接.

错误预设( E)POST /__admin/faults {"preset": "<name>", "count"?: n}· ; GET /__admin/faults/presets: publish_throttled (单位:千美元)429 ThrottlingException, (中文(简体) ), publish_unauthorized (单位:千美元)401 UnauthorizedException, (中文(简体) ), publish_internal_failure (单位:千美元)500 InternalFailureException, (中文(简体) ), connect_not_authorized (结束) 0x87, (中文(简体) ), connect_bad_credentials (单位:千美元)0x86, (中文(简体) ), connect_quota_exceeded (单位:千美元)0x97) (中文(简体) ). CONNECT是故障操作 MqttConnect,所以任何原因 代码可以强制 : {"operationId": "MqttConnect", "effect": "connack", "params": {"reasonCode": 137}}。 。 。 .

命名空间

平行工人通过命名空间孤立自己. HTTP : (韩语) x-mockingbird-namespace页:1 /__admin/ns/<name> 前缀在终点,或通过访问密钥 id (单位:千美元)PUT /__admin/credentials {"credentials": {"<AWS_ACCESS_KEY_ID>": "<namespace>"}}(原始内容存档于2017-09-26). MQTT: the WebSocket URL 网络软件 ws://…/__admin/ns/<name>/mqtt,或由 CONNECT 键入的同一证书地图 用户名(没有查询字符串),然后是其客户端 ID。 未实现客户端使用默认值 名称空间.

未核实

文档不会解决这些问题; 模拟者的选择被声明为套房不会 给卖家弄错了

  • 圆满之体. API的参考文献说 Publish 回答空正文; AWS 的自定义 认证教程显示 {"message": "OK", "traceId": "…"}。模拟器发送 后者,SDK忽略了这一点.
  • 拒证. 未签名的请求或未验证仿真器的签名 答题 403 {"message": "Forbidden", "traceId"} 与 x-amzn-ErrorType: ForbiddenException数字 : 主体是拒绝的自定义授权签名的 AWS 文件、状态和 标题是推断的。 用于有效签名而无需 iot:Publish 它回答了文件 401 UnauthorizedException;无论AWS回答401还是403,都没有确认.
  • AWS 是否发送 x-amzn-ErrorType,则 message 每个文本 400,则 HTTP 错误 128 KB以上的有效载荷(模拟器用途) 400 InvalidRequestException) (中文(简体) ).
  • "128 KB"和"146 KB"被取为131072和149504字节. AWS的MQTT页面也提到 最大包大小"不能超过128 KB";使用配额页146 KB.
  • 客户所看到的 isAuthenticated: false (AWS说它"结束了连接"; 模拟器发送 CONNACK 0x87 首先,对于一个超越限制范围或始于 $ (AWS说此类操作"可以导致终止连接";模拟器回答 苏巴克 0x8F / 弹夹 0x90 并保持连接),以及超大小的MQTT有效载荷 (DISCONENECT 存档副本) 0x95) (中文(简体) ).
  • 一个QoS 2 子公司获得没有SUBACK是AWS的有记录的行为,在没有协议的情况下声明 版本;它被应用于已写入的 MQTT 5 .
  • 当服务器保持生存时,接收最大值(100, 从未承认出版物配额中提取) 发送,指定客户端 ID 的格式,以及 Lambda 事件是否 username 包括查询字符串(模拟器将其剥去).
  • 签名日期不与时钟相对照,所以套房可以冻结时间.

故意不模拟

  • MQTT 3.1和3.1.1(与该协议的回回码重用), TLS, X. 509 客户端 证书、 ALPN 和 SNI 以及 SigV4 指定的 WebSocket URL .
  • 自定义对 HTTP 、 符号签名和 disconnectAfterInSeconds 编号 : refreshAfterInSeconds (接受,未执行).
  • 政策 Condition, (中文(简体) ), NotAction 财务报告和审定财务报表 NotResource (拒绝使用这些文件)政策 变量 ${iot:ClientId},以及 iot:RetainPublish。 。 。 .
  • 保留消息: CONNACK 表示保留可使用 0, 保留 MQTT 的发布被解答 分解系统 0x9A,以及 retain=true 超过HTTP是 400AWS本身支持它们.
  • 将信件(收受于CONNECT,从未发布),共享订阅(SUBACK) 0x9E, (中文(简体) ), 保留动态超时、消息过期、外出主题别名和保留 $aws/… 专题.
  • 比率和计数配额(每秒publishes、每条连接或每条附属CRIBE、, 存储会话的每秒重放10个消息.
  • 记录 阴影 规则和行动 工作 供给 其它数据平面 业务、账单和基础设施管理.

API 密码

导出仁爱说明
createRuntime函数服务合同的模拟者。 选项 : settings, (中文(简体) ), authorizer, (中文(简体) ), clock, (中文(简体) ), seed, (中文(简体) ), adminPrefix, (中文(简体) ), adminKey, (中文(简体) ), onLog, (中文(简体) ), sqlite添加 attach(transport, info?, namespace?) 为 MQTT 连接, webSocketPath(pathname), (中文(简体) ), endpoints,以及 stop()。 。 。 .
AwsIotAPI类一个命名空间 : fetch(request) 页:1 Publish, (中文(简体) ), broker 为MQTT, state, (中文(简体) ), reset()选项: sqlite, (中文(简体) ), now, (中文(简体) ), namespace, (中文(简体) ), settings, (中文(简体) ), authorizer, (中文(简体) ), connectFault。 。 。 .
AWS_IOT_PRESETS对象每个命名的断层预设.
AWS_IOT_NAMESPACE字符串服务名称, "aws-iot"。 。 。 .
SIGNING_NAME字符串"iotdata",SigV4签名名称.
MQTT_CONNECT_OPERATION, (中文(简体) ), MQTT_WEBSOCKET_PATH字符串"MqttConnect"(一) 操作id出错规则用于CONNECT;以及 "/mqtt"。 。 。 .
MAX_PAYLOAD_BYTES, (中文(简体) ), MAX_PACKET_SIZE, (中文(简体) ), MAX_TOPIC_BYTES, (中文(简体) ), MAX_TOPIC_SLASHES, (中文(简体) ), MAX_CLIENT_ID_BYTES, (中文(简体) ), MAX_MESSAGE_EXPIRY_SECONDS, (中文(简体) ), MAX_PERSISTENT_SESSION_EXPIRY_SECONDS, (中文(简体) ), KEEP_ALIVE_RANGE数字AWS IOT Core的极限是模拟器执行的.
DEFAULT_SETTINGS对象地区 us-east-1账户 123456789012,无证书或授权人,1小时会议配额.
parseSettings函数验证 JSON 的设置补丁; 丢出错误字段的命名 .
parsePolicyDocument, (中文(简体) ), isAllowed, (中文(简体) ), resourceArn, (中文(简体) ), PolicyError函数,类分析一个政策文件(对象或JSON字符串),对它进行动作和目标评价,并构建 ARN 以检查动作.
accessKeyCredential, (中文(简体) ), splitUsername函数已签名请求的存取密钥 ID; MQTT 用户名和授权方的查询字符串名( 如何将权限映射到命名空间) .
ReasonCode对象MQTT 5 名下理性码.
document, (中文(简体) ), operationIds, (中文(简体) ), supportedOperationIds数值HTTP合同及其操作代号.
createServer, (中文(简体) ), connectStream, (中文(简体) ), loadSettingsFile, (中文(简体) ), serveTarget, (中文(简体) ), DEFAULT_PORT, (中文(简体) ), DEFAULT_MQTT_PORT (单位:千美元)./server(中文(简体) )节点服务HTTP、WebSocket和TCP{url, mqttUrl, mqttPort, wsUrl, runtime, close()}; 选项添加 port, (中文(简体) ), mqttPort, (中文(简体) ), host, (中文(简体) ), sweepMs; 正在处理的 MQTT 流; 读取 --settings 文件; 该 serve CLI目标;港口8851和8883.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-aws-iot 共发布 19 个版本,首次发布于 2026/10/11;过去 12 个月发布了 19 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.10.0latest2026/11/11今天
0.9.82026/11/038 天前
0.9.72026/11/038 天前
0.9.62026/11/038 天前
0.9.52026/11/038 天前
0.9.42026/11/038 天前

关于 @crvouga/mockingbird-service-aws-iot 的常见问题

@crvouga/mockingbird-service-aws-iot 是什么?

AWS IoT Core Data平面的状态仿真器:由SigV4签名的HTTP Publishing和由TCP和WebSocket负责的MQTT 5消息经纪人,有自定义授权政策和持续会话.

如何安装 @crvouga/mockingbird-service-aws-iot?

在项目目录运行 npm install @crvouga/mockingbird-service-aws-iot,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-aws-iot,可以用 npx mockingbird-aws-iot 直接运行。

@crvouga/mockingbird-service-aws-iot 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-aws-iot 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-aws-iot 可以商用吗?

@crvouga/mockingbird-service-aws-iot 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-aws-iot 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-aws-iot 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,002 次,日均约 100 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-aws-iot 还在维护吗?

最新版本 0.10.0 发布于 2026/11/11(今天);至今共发布 19 个版本,其中过去 12 个月发布了 19 个;首次发布于 2026/10/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。