debugging-with-ably-cli

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Debugging with Ably CLI

使用Ably CLI进行调试

The Ably CLI (
@ably/cli
, install via
npm install -g @ably/cli
) lets you observe, test, and simulate Ably operations from the terminal — faster than console.log or browser DevTools.
Discovering commands: Run
ably --help
for command groups,
ably <command> --help
for subcommands, flags, and examples. The CLI is self-documenting. This skill teaches what's possible and when to use it.

Ably CLI(
@ably/cli
,可通过
npm install -g @ably/cli
安装)让你从终端观测、测试和模拟Ably操作——比console.log或浏览器开发者工具更高效。
查找命令: 运行
ably --help
查看命令组,运行
ably <command> --help
查看子命令、参数和示例。该CLI自带文档说明。本技能将讲解它能实现什么以及何时使用

1. Diagnostic Decision Tree

1. 诊断决策树

Messages not arriving
├── Is anyone on the channel?        → list channels with a prefix filter
├── Was anything published?          → check channel history (2 min only without persistence)
├── Can I see messages live?         → subscribe to the channel
├── Test round-trip                  → subscribe in background, publish from main terminal
└── Check channel lifecycle          → subscribe to channel lifecycle logs, or inspect the channel in the dashboard

Presence not working
├── Who is actually present?         → subscribe to presence on the channel
├── Simulate a client joining        → enter presence with custom client-id and data
├── Check presence member count      → get channel occupancy
│   (stale members? ungraceful disconnects take ~15s to be removed)
└── Watch all presence events        → subscribe to logs filtered by channel.presence, or inspect the channel in the dashboard

Connection problems
├── Can I connect at all?            → test connection (try ws and xhr separately)
├── Is Ably up?                      → check service status
├── Watch connection lifecycle       → subscribe to connection lifecycle logs
└── Connection count vs plan limit   → check app stats in live mode

Auth errors
├── Is the API key valid?            → test connection with the specific key
├── What capabilities does key have? → list auth keys
├── Using tokens (JWT or Ably)?      → issue a test token via CLI to verify the key can create valid tokens
│   (CLI token issuance tests the key, not your app's authUrl/authCallback)
├── Token expired (40142)?           → check TTL and renewal config (authUrl/authCallback)
└── Look up the error code           → ask the support agent or fetch help.ably.io/error/{code}

Channel state / lifecycle issues
├── Watch channel events             → subscribe to channel lifecycle logs
├── Watch all app meta events        → subscribe to all logs
├── Check channel occupancy          → get or subscribe to occupancy
└── Check channel rules/config       → list channel rules (persistence, TLS, push, etc.)

Push notifications not working
├── Watch push delivery logs         → subscribe to push logs (meta channel)
├── Check push log history           → get push log history
├── Is push enabled on namespace?    → list channel rules, check push-enabled
└── Check integration rules          → list integrations, check source type and channel filter

Integration rules not firing
├── List all integrations            → list integrations to see rules, source types, status
├── Check source type matches        → source can be channel.message, channel.presence,
│                                      channel.lifecycle, or presence.message
├── Check channel filter             → filter pattern must match the channel name
├── Is the rule enabled?             → check integration status (enabled/disabled)
└── Check for delivery errors        → check log history — the log metachannel captures
                                       errors sending on integrations

Queue issues
├── Are queues configured?           → list queues
├── Is the integration routing to it?→ list integrations, check AMQP rule target
└── Check message flow               → subscribe to the source channel to verify messages exist

Chat room issues (@ably/chat)
├── Are messages flowing?            → subscribe to room messages
│   (if CLI sees messages but app doesn't → room.attach() likely missing)
├── Check room presence              → subscribe to room presence
├── Check occupancy                  → get room occupancy
├── Check underlying channel events  → inspect the room's channels in the dashboard, or subscribe to channel lifecycle logs and look for the room's channel names
└── Send a test message              → send a message to the room from CLI

Spaces issues (@ably/spaces)
├── Who is in the space?             → subscribe to space members
├── Watch cursors                    → subscribe to space cursors
├── Watch locations                  → subscribe to space locations
└── Check locks                      → get all locks in the space

Messages not arriving
├── Is anyone on the channel?        → list channels with a prefix filter
├── Was anything published?          → check channel history (2 min only without persistence)
├── Can I see messages live?         → subscribe to the channel
├── Test round-trip                  → subscribe in background, publish from main terminal
└── Check channel lifecycle          → subscribe to channel lifecycle logs, or inspect the channel in the dashboard

Presence not working
├── Who is actually present?         → subscribe to presence on the channel
├── Simulate a client joining        → enter presence with custom client-id and data
├── Check presence member count      → get channel occupancy
│   (stale members? ungraceful disconnects take ~15s to be removed)
└── Watch all presence events        → subscribe to logs filtered by channel.presence, or inspect the channel in the dashboard

Connection problems
├── Can I connect at all?            → test connection (try ws and xhr separately)
├── Is Ably up?                      → check service status
├── Watch connection lifecycle       → subscribe to connection lifecycle logs
└── Connection count vs plan limit   → check app stats in live mode

Auth errors
├── Is the API key valid?            → test connection with the specific key
├── What capabilities does key have? → list auth keys
├── Using tokens (JWT or Ably)?      → issue a test token via CLI to verify the key can create valid tokens
│   (CLI token issuance tests the key, not your app's authUrl/authCallback)
├── Token expired (40142)?           → check TTL and renewal config (authUrl/authCallback)
└── Look up the error code           → ask the support agent or fetch help.ably.io/error/{code}

Channel state / lifecycle issues
├── Watch channel events             → subscribe to channel lifecycle logs
├── Watch all app meta events        → subscribe to all logs
├── Check channel occupancy          → get or subscribe to occupancy
└── Check channel rules/config       → list channel rules (persistence, TLS, push, etc.)

Push notifications not working
├── Watch push delivery logs         → subscribe to push logs (meta channel)
├── Check push log history           → get push log history
├── Is push enabled on namespace?    → list channel rules, check push-enabled
└── Check integration rules          → list integrations, check source type and channel filter

Integration rules not firing
├── List all integrations            → list integrations to see rules, source types, status
├── Check source type matches        → source can be channel.message, channel.presence,
│                                      channel.lifecycle, or presence.message
├── Check channel filter             → filter pattern must match the channel name
├── Is the rule enabled?             → check integration status (enabled/disabled)
└── Check for delivery errors        → check log history — the log metachannel captures
                                       errors sending on integrations

Queue issues
├── Are queues configured?           → list queues
├── Is the integration routing to it?→ list integrations, check AMQP rule target
└── Check message flow               → subscribe to the source channel to verify messages exist

Chat room issues (@ably/chat)
├── Are messages flowing?            → subscribe to room messages
│   (if CLI sees messages but app doesn't → room.attach() likely missing)
├── Check room presence              → subscribe to room presence
├── Check occupancy                  → get room occupancy
├── Check underlying channel events  → inspect the room's channels in the dashboard, or subscribe to channel lifecycle logs and look for the room's channel names
└── Send a test message              → send a message to the room from CLI

Spaces issues (@ably/spaces)
├── Who is in the space?             → subscribe to space members
├── Watch cursors                    → subscribe to space cursors
├── Watch locations                  → subscribe to space locations
└── Check locks                      → get all locks in the space

2. Key Debugging Facts

2. 核心调试要点

  • Channel names are case-sensitive. Mismatched names between publisher and subscriber is a common bug. List active channels to see what actually exists.
  • History defaults to 2 minutes. Without persistence, history only covers Ably's connection recovery window. Check channel rules for
    persisted: true
    . If not enabled, tell the user and suggest enabling via channel rules or the dashboard.
  • Presence requires clientId AND capability. The clientId must be set at connection time (not per-presence-enter). Entering presence requires the
    presence
    capability; subscribing to presence events requires
    subscribe
    capability. A client can observe who's present without entering itself. Without the right capability, presence operations fail with 40160.
  • Capability scope on channel names. A key with
    publish:["chat:*"]
    allows publish on channels starting with
    chat:
    (e.g.,
    chat:room-1
    ), but NOT on a channel literally named
    chat
    . The colon separator and wildcard pattern matter — this is a common cause of 40160 errors.
  • Token expiry (40142). Tokens have a TTL. If the client has no
    authUrl
    or
    authCallback
    configured for renewal, the token expires; any connection will fail and any other API requests will be refused. Test token issuance via the CLI to verify auth flow works independently of the app.
  • Presence removal delay. Ungraceful disconnects take ~15 seconds to be removed by Ably.
  • Occupancy reveals duplicate subscriptions. If subscriber count is much higher than expected, check for duplicate subscriptions (React StrictMode, missing useEffect cleanup, multiple Ably client instances).
  • Token vs key capabilities. Keys and tokens issued from them can have different capabilities; the rights of a token is the intersection between the rights of the key, and the specific rights specified in the token. Debug 40160 errors by checking both the key capabilities AND the token creation code on the server.
  • Metachannel logs require
    [meta]*
    capability.
    All
    ably logs
    commands subscribe to logs metachannels (
    [meta]log
    ,
    [meta]channel.lifecycle
    , etc.). A key scoped to
    *
    does not match metachannels — the key needs
    [meta]*
    or
    [*]*
    in its capability resource list. The app's root API key has
    [*]*
    by default. If
    ably logs
    commands fail with 40160, check the key's capability scope. For deep inspection of a single channel (per-channel stats, regional breakdown, attached integrations), use
    ably channels inspect <channel>
    to open the dashboard's channel inspector — this uses privileged inspection metachannels (
    [meta]inspect:*
    ) not currently available to the CLI.
  • Transport fallback. If WebSocket is blocked, the SDK falls back to XHR streaming. Test both transports separately to confirm which works.
  • Non-default environments. If the app uses a sandbox or custom environment, log in with
    ably accounts login --endpoint <host>
    to target the right cluster.
  • Error message text > error code. Ably error codes are broad categories (e.g., 40000 covers many variants). Always read the error message text for the specific cause. Every code has a help page at
    help.ably.io/error/{code}
    , or use
    ably support ask "error {code}"
    .

  • 通道名称区分大小写。发布者和订阅者之间的名称不匹配是常见问题。列出活跃通道查看实际存在的通道名称。
  • 历史记录默认保留2分钟。未启用持久化时,历史记录仅覆盖Ably的连接恢复窗口。检查通道规则是否设置了
    persisted: true
    。如果未启用,告知用户并建议通过通道规则或控制台启用。
  • 状态功能需要clientId和权限。必须在连接时设置clientId(而非每次进入状态时)。进入状态需要
    presence
    权限;订阅状态事件需要
    subscribe
    权限。客户端可以查看当前在线状态而无需自身进入状态。权限不足时,状态操作会返回40160错误。
  • 通道名称的权限范围。拥有
    publish:["chat:*"]
    权限的密钥允许在以
    chat:
    开头的通道(例如
    chat:room-1
    )发布消息,但不允许在字面名为
    chat
    的通道发布。冒号分隔符和通配符规则非常重要——这是40160错误的常见原因。
  • 令牌过期(40142)。令牌有TTL有效期。如果客户端未配置
    authUrl
    authCallback
    用于续期,令牌过期后,所有连接会失败,其他API请求也会被拒绝。通过CLI签发令牌,可独立于应用测试认证流程是否正常。
  • 状态移除延迟。非优雅断开连接的客户端需要约15秒才会被Ably移除。
  • 通道占用情况可暴露重复订阅。如果订阅者数量远高于预期,检查是否存在重复订阅(React StrictMode、useEffect未清理、多个Ably客户端实例)。
  • 令牌与密钥的权限差异。密钥和从其签发的令牌权限可能不同;令牌的权限是密钥权限与令牌指定权限的交集。调试40160错误时,需同时检查密钥权限和服务器端的令牌生成代码。
  • 元通道日志需要
    [meta]*
    权限
    。所有
    ably logs
    命令都会订阅日志元通道(
    [meta]log
    [meta]channel.lifecycle
    等)。权限为
    *
    的密钥无法匹配元通道——密钥需要在权限资源列表中包含
    [meta]*
    [*]*
    。应用的根API密钥默认拥有
    [*]*
    权限。如果
    ably logs
    命令返回40160错误,检查密钥的权限范围。如需深度检查单个通道(单通道统计、区域分布、关联集成),使用
    ably channels inspect <channel>
    打开控制台的通道检查器——这会使用当前CLI不支持的特权检查元通道(
    [meta]inspect:*
    )。
  • 传输方式降级。如果WebSocket被阻止,SDK会降级为XHR流传输。分别测试两种传输方式,确认哪种可用。
  • 非默认环境。如果应用使用沙箱或自定义环境,使用
    ably accounts login --endpoint <host>
    登录以定位正确的集群。
  • 错误消息文本优先于错误代码。Ably错误代码是宽泛的分类(例如40000涵盖多种情况)。务必阅读错误消息文本获取具体原因。每个错误代码都有对应的帮助页面
    help.ably.io/error/{code}
    ,也可使用
    ably support ask "error {code}"
    查询。

3. CLI Authentication

3. CLI认证

The CLI needs credentials. Two approaches:
Credentials from the project (quick, no login): Set
ABLY_API_KEY
as an environment variable. Find the key from the project's environment files and export it (e.g.
export ABLY_API_KEY=...
). Alternatively, if you have a token (e.g., from the app's auth server), use
ABLY_TOKEN
instead. If the key is for a production app, note this to the user before using it.
Log in to the CLI (for extended debugging or account-level commands):
ably login
opens a browser for OAuth. Once logged in, use
ably apps list
and
ably apps switch
to target the right app, and
ably auth keys list
to see available keys and their capabilities.
If no credentials are available, ask the user: "I need Ably credentials to debug this. Can you share the API key from your .env, or run
ably login
?"

CLI需要凭证,有两种方式:
从项目获取凭证(快速,无需登录):
ABLY_API_KEY
设置为环境变量。从项目的环境文件中找到密钥并导出(例如
export ABLY_API_KEY=...
)。或者,如果你有令牌(例如来自应用的认证服务器),可以使用
ABLY_TOKEN
替代。如果该密钥属于生产应用,在使用前需告知用户。
登录CLI(用于深度调试或账户级命令):
ably login
会打开浏览器进行OAuth认证。登录后,使用
ably apps list
ably apps switch
切换到目标应用,使用
ably auth keys list
查看可用密钥及其权限。
如果没有可用凭证,请询问用户:“我需要Ably凭证来进行调试。能否分享.env文件中的API密钥,或者运行
ably login
登录?”

4. What the CLI Can Do

4. CLI核心功能

Observe (Read-Only)

观测(只读)

Subscribe to channels, presence, occupancy, logs, and stats in real time — you see exactly what Ably sees.
  • Channel messages: Subscribe to one or more channels. Supports wildcards and rewind (replay recent messages on attach).
  • Presence: Watch who enters and leaves, with their client IDs and data payloads.
  • Occupancy: Snapshot or live stream of publishers, subscribers, and presence members on a channel.
  • Logs (meta channels): Channel lifecycle, connection lifecycle, presence events, and push notification delivery logs. Filter by type (
    channel.lifecycle
    ,
    channel.occupancy
    ,
    channel.presence
    ,
    connection.lifecycle
    ,
    push.publish
    ), rewind to catch recent events.
  • Push notification logs: Dedicated push log stream and history — see delivery attempts, failures, and device targeting.
  • History: Past messages on a channel (2 minutes without persistence — see Key Debugging Facts).
  • Stats: App or account statistics with a live polling mode. Check connection counts against plan limits.
  • Channel list: Currently active channels with prefix filtering.
  • Connection test: Verify connectivity across transports (WebSocket, XHR) to isolate network or proxy issues.
实时订阅通道、状态、占用情况、日志和统计数据——你能看到Ably接收的所有内容。
  • 通道消息:订阅一个或多个通道,支持通配符和回退(连接时重播近期消息)。
  • 状态信息:查看客户端的进入和离开事件,以及对应的client ID和数据负载。
  • 通道占用:获取或实时订阅通道上的发布者、订阅者和状态成员数量。
  • 日志(元通道):通道生命周期、连接生命周期、状态事件和推送通知投递日志。可按类型过滤(
    channel.lifecycle
    channel.occupancy
    channel.presence
    connection.lifecycle
    push.publish
    ),支持回退查看近期事件。
  • 推送通知日志:专属的推送日志流和历史记录——查看投递尝试、失败和设备目标信息。
  • 历史记录:通道的过往消息(未启用持久化时仅保留2分钟——参考核心调试要点)。
  • 统计数据:应用或账户的统计数据,支持实时轮询模式。检查连接数是否超出套餐限制。
  • 通道列表:当前活跃的通道,支持前缀过滤。
  • 连接测试:验证不同传输方式(WebSocket、XHR)的连通性,排查网络或代理问题。

Simulate

模拟

Act as a participant — simulate one end of a conversation to test the other (client when debugging server, server when debugging client).
  • Publish: Send messages with event names, JSON, or plain text. Publish repeatedly with configurable count and delay to simulate traffic.
  • Batch publish: Publish to multiple channels in a single request.
  • Presence enter: Join a channel with custom client ID and data (e.g.,
    {"role": "server"}
    ).
  • Chat: Full room simulation — messages, presence, typing, reactions.
  • Spaces: Members, cursors, locations, locks.
  • Benchmarking: Publisher/subscriber throughput and latency testing with configurable rates and message sizes.
作为参与者模拟通信一端——调试服务器时模拟客户端,调试客户端时模拟服务器。
  • 发布消息:发送带事件名、JSON或纯文本的消息。支持按配置的次数和延迟重复发布,模拟流量。
  • 批量发布:单次请求向多个通道发布消息。
  • 进入状态:使用自定义client ID和数据(例如
    {"role": "server"}
    )加入通道。
  • 聊天室模拟:完整的房间功能模拟——消息、状态、输入提示、反应。
  • Spaces模拟:成员、光标、位置、锁功能。
  • 基准测试:可配置速率和消息大小的发布者/订阅者吞吐量和延迟测试。

Manage

管理

Query and modify app configuration to diagnose config-related issues.
  • Channel rules (namespaces): Check and configure persistence, push, TLS-only, batching, conflation, and channel registry settings.
  • API keys: List capabilities, create, revoke, switch active key.
  • Token issuance: Issue JWTs (or Ably tokens if the app uses these) to test auth flows in isolation. Also revoke tokens.
  • Apps: List, create, switch, configure.
  • Integrations: List and inspect integration rules — webhooks, Lambda, Kafka, AMQP, and others. Check source types (channel.message, channel.presence, channel.lifecycle, presence.message), channel filters, and enabled/disabled status.
  • Queues: List, create, and delete Ably message queues.
查询和修改应用配置,诊断配置相关问题。
  • 通道规则(命名空间):查看和配置持久化、推送、仅TLS、批量处理、合并和通道注册设置。
  • API密钥:查看权限、创建、吊销、切换活跃密钥。
  • 令牌签发:签发JWT(或Ably令牌,如果应用使用)以独立测试认证流程,也支持吊销令牌。
  • 应用管理:列出、创建、切换、配置应用。
  • 集成管理:列出和检查集成规则——Webhook、Lambda、Kafka、AMQP等。检查源类型(channel.message、channel.presence、channel.lifecycle、presence.message)、通道过滤器和启用/禁用状态。
  • 队列管理:列出、创建和删除Ably消息队列。

Get Help

获取帮助

  • AI support agent (powered by Inkeep):
    ably support ask "your question"
    — searches Ably docs and FAQs. Use
    --continue
    for follow-ups.
  • Service status:
    ably status
    checks platform health.

  • AI支持助手(由Inkeep提供支持):
    ably support ask "your question"
    ——搜索Ably文档和常见问题。使用
    --continue
    进行跟进提问。
  • 服务状态
    ably status
    检查平台健康状况。

5. Long-Running Commands

5. 长运行命令

Many commands (
subscribe
,
presence enter
,
stats --live
,
occupancy subscribe
) are long-running — they stream output until Ctrl+C or
--duration N
expires. Run these as background tasks so they don't block your workflow. Start a subscribe in the background, reproduce the issue, then check the output.

许多命令(
subscribe
presence enter
stats --live
occupancy subscribe
)是长运行命令——它们会持续输出直到按下Ctrl+C或
--duration N
超时。请将这些命令作为后台任务运行,避免阻塞工作流。在后台启动订阅,重现问题,然后查看输出。

6. Connection and Channel State Reference

6. 连接与通道状态参考

Connection States

连接状态

StateMeaningDiagnostic
connecting
Attempting connectionNormal on startup; if stuck, check network/auth
connected
Active WebSocketHealthy
disconnected
Temporary loss, SDK retriesTransient is normal; recurring = network issues → watch connection lifecycle logs
suspended
Offline >2 min, less frequent retriesTest connection to check connectivity
failed
Permanent failure, SDK won't retryAlmost always auth — test with the specific API key
closed
Explicitly closed by codeSearch for
.close()
calls
状态含义诊断建议
connecting
正在尝试连接启动时为正常状态;如果卡住,检查网络/认证
connected
WebSocket连接活跃状态健康
disconnected
临时断开,SDK会重试短暂断开正常;频繁断开=网络问题 → 查看连接生命周期日志
suspended
离线超过2分钟,重试频率降低测试连接以检查网络连通性
failed
永久连接失败,SDK不会重试几乎都是认证问题 → 使用指定API密钥测试连接
closed
被代码显式关闭查找代码中的
.close()
调用

Channel States

通道状态

StateMeaningDiagnostic
initialized
Channel object created, not yet attachedNormal before first subscribe/publish
attaching
Requesting attach from serverIf stuck, check connection state and auth capabilities
attached
Active — messages flowingHealthy
detaching
Requesting detachNormal during cleanup
detached
Not attached, no messages flowingCheck if
detach()
was called intentionally
suspended
Attach failed, will retryUsually follows connection suspension — check connection state first
failed
Permanent channel failureOften capability denied (40160) or invalid channel name

状态含义诊断建议
initialized
通道对象已创建,尚未连接首次订阅/发布前为正常状态
attaching
正在向服务器请求连接如果卡住,检查连接状态和认证权限
attached
已连接,消息正常传输状态健康
detaching
正在请求断开连接清理时为正常状态
detached
未连接,消息无法传输检查是否有意调用了
detach()
suspended
连接失败,将重试通常跟随连接暂停 → 先检查连接状态
failed
通道永久连接失败通常是权限不足(40160)或通道名称无效

7. Environment-Specific Gotchas

7. 特定环境的注意事项

EnvironmentSymptomRoot CauseDiagnostic
Next.js SSRConnection fails during renderNo WebSocket in server-side renderGuard with
typeof window
or
useEffect
Serverless (Lambda, Edge)Stale/frozen connectionsConnection frozen between invocationsUse
Ably.Rest
server-side
React StrictModeDuplicate messages, presence flickerDouble-render duplicates subscriptionsCheck occupancy — much higher than expected = duplicates
CSP headersWebSocket blockedAbly domains not in
connect-src
Test connection — ws fails, xhr works = CSP
Corporate proxyWebSocket fails silentlyProxy blocking upgradeTest connection — ws fails, xhr works = proxy
Mobile backgroundMessages missed after resumeOS kills WebSocketCheck channel history for messages sent during gap
环境症状根本原因诊断建议
Next.js SSR渲染期间连接失败服务端渲染中不支持WebSocket使用
typeof window
useEffect
进行防护
无服务器架构(Lambda、Edge)连接过期/冻结调用之间连接被冻结服务端使用
Ably.Rest
React StrictMode重复消息、状态闪烁双重渲染导致订阅重复查看通道占用情况——远高于预期值=存在重复订阅
CSP头WebSocket被阻止Ably域名未加入
connect-src
测试连接——ws失败,xhr成功=存在CSP限制
企业代理WebSocket静默失败代理阻止升级请求测试连接——ws失败,xhr成功=代理问题
移动端后台恢复后错过消息系统关闭了WebSocket查看通道历史记录,获取间隙期间发送的消息