MsgMesh 文件
概念 · 投遞保證 · 接入方式 ・ 公開 Beta
MsgMesh 是一套託管的持久事件總線:你發一則訊息,人跟 AI 可以同時收到;對方沒上線,訊息留著、晚到也能倒回去重看。排隊、重試、補送、斷線重連這些收發後台的雜事由平台負責。
這一頁講的是心智模型與語意——每個名詞代表什麼、四種收訊方式各自適合什麼、「至少送達一次」在你的程式裡實際會長什麼樣。逐一端點的請求/回應格式請看 API 文件;想直接動手,快速接入有可以複製的片段。
1.核心概念
整套系統只有四個名詞,先把它們分清楚,後面都好懂:
| 名詞 | 是什麼 |
|---|---|
| topic | 一條具名的訊息流,例如 orders、chat。發布與訂閱都以 topic 為單位。topic 屬於你的租戶,彼此隔離。 |
| 訊息 | 一段你自己決定格式的內容(通常是 JSON)。平台不解讀內容,只負責可靠地送到並保存到保留期為止。 |
| 房間(room) | topic 內部的分流標籤,例如把 chat 一個 topic 切成 room-42、room-43。讓「房間數」不必等於「topic 數」。 |
| 金鑰 / token | 呼叫平台的憑證。長期 API 金鑰放伺服器端;瀏覽器只拿由你後端換發的短期 token。 |
沒有「佇列」「交換機」「綁定」這類需要先設計拓樸的東西——建一個 topic 就可以開始發了。
2.四種收訊方式
同一條 topic 可以同時被多種方式消費。差別在「誰主動」與「連線活多久」:
| 方式 | 適合 | 要注意 |
|---|---|---|
| 長輪詢(poll) | 後端服務、批次處理、Node 22 以前的環境。用消費群組記錄進度,重啟接得回來。 | 整條 topic 的 firehose,不能只收某個房間。 |
| SSE | 瀏覽器即時顯示。瀏覽器原生 EventSource 自帶重連,不裝任何套件也能接。 | 單向(只收不發),發訊走一般 HTTP。 |
| WebSocket | SSE 被中間裝置擋掉時,或你本來就有 WebSocket 基礎建設。 | 沒有原生自動重連——用官方 SDK,它已經幫你管好退避與換 token。 |
| Webhook | 你希望「平台主動打你的 HTTPS 端點」,不維持任何長連線。 | 目的位址必須是公開可達的 https;指向內網會被擋(見下)。端點暫時不通會自動重試;回 404 這種「再送也一樣」的狀態碼則不重試,第一次就進死信佇列(見下)。 |
3.投遞保證:至少一次、續傳、去重
這一節是整份文件最值得讀完的部分,因為它決定你的程式要不要處理重複。
至少送達一次(at-least-once)。平台承諾訊息不會因為你斷線而遺失,但不承諾只送一次。斷線重連時,伺服器會從你上次看到的位置往後補,而邊界上難免重送一兩則你已經看過的。
續傳靠游標。每一則訊息都帶一個 <分割>-<位移> 形式的游標(單調遞增)。你的 client 記住最後看到的那一個,重連時帶回去,伺服器就從那裡接上——斷線期間漏掉的會被補回來,而不是消失。
去重是 client 的事,但 SDK 已經幫你做了。官方 SDK(JavaScript 與 Python)會依游標逐分割去重:位移不大於「該分割已經看過的最大值」就跳過。所以用 SDK 的話,你的 onMessage 收到的就是不重複的訊息。
補不回來的時候會明講。如果斷線太久、超出伺服器的重播窗,伺服器會送一個 msgmesh-resync 訊號,意思是「我沒辦法保證補完整」。收到它就自己重抓一次快照;之後的即時訊息會依游標和快照自動去重。
順序。同一個分割內保持發布順序。要讓一群訊息嚴格有序,就用同一個房間(房間即分割鍵)。
4.憑證:伺服器端金鑰 vs 瀏覽器短期 token
長期 API 金鑰只放伺服器端。它建立時只會以明文顯示一次,之後平台只存雜湊。別提交進版控、別寫進日誌。
瀏覽器一律不要放 API 金鑰——前端的任何東西都會外流。正確做法是token broker:你的後端持金鑰,呼叫 POST /v1/tokens 換一個短命、降權的 token 給前端,前端從頭到尾只拿得到那個會過期的 token。官方 SDK 支援這個模式(給它一個取 token 的 callback),快取、到期前重取、重連換新都由 SDK 處理,對你的程式是透明的。
權限分兩層。角色鍵有 admin / producer / consumer;需要更細就用能力鍵,直接寫明「哪些操作 × 哪些 topic × 哪些房間」。降權時只能變窄,越權會被拒絕(403)。
5.房間:路由與隔離
房間有兩層,分清楚很重要,因為只做第一層沒有安全性:
① 路由(過濾)。發布時帶房間鍵、訂閱時指定房間,就只收到那個房間的訊息。不指定房間 = 收整條 topic(向後相容)。
② 隔離(平台強制)。在憑證的能力裡寫明允許的房間,平台就會強制它只能收發那些房間,越界回 403。
6.錯誤與狀態碼
非 2xx 一律回 {"error": "..."};SDK 會依狀態碼丟出可用 instanceof 判別的型別。
| 狀態 | 意思 | 你該怎麼做 |
|---|---|---|
400 / 422 | 參數或內容不合法 | 修請求。重試沒有意義。 |
401 | 憑證無效或已不存在 | 終態。重新取得憑證,不要無限重試。 |
403 | 權限不足,或帳務停權 | 可能可恢復(例如充值後自動解封),適合退避後重試。 |
404 | 資源不存在 | 檢查名稱;若開了嚴格 topic 閘門,未建立的 topic 也會是 404。 |
429 | 超出速率限制或免費含量 | 退避後重試;持續發生代表該升級方案。 |
500 類回應會附一個 request_id,回報問題時附上它可以直接定位。
7.三分鐘接上
在面板註冊、簽一把金鑰(明文只顯示一次),然後:
npm i @msgmesh/sdk # JavaScript / TypeScript
pip install msgmesh # Python(同一組 API,snake_case)
import { MsgMesh } from "@msgmesh/sdk";
const mq = new MsgMesh({
apiKey: process.env.MSGMESH_KEY, // 長期金鑰,只放伺服器端
controlPlaneUrl: "...", gatewayUrl: "...", realtimeUrl: "...",
});
await mq.createTopic("orders");
await mq.publish("orders", { hello: 1 });
const msgs = await mq.poll("orders", { group: "g1" });
不用 SDK 也完全可以——一切都是普通 HTTP:帶 Authorization: Bearer <金鑰> 打對應端點即可,格式見 API 文件。
8.給 AI agent 用(MCP)
MsgMesh 有官方 MCP server,所以支援 MCP 的 AI 工具(例如 Claude Code)可以直接把事件流當成輸入源:agent 用 watch_topic 等在那裡,外部一發訊息就醒過來、只收到新的事件,然後決定要做什麼。
npx @msgmesh/mcp-server # 只需要設 MQ_API_KEY
這跟「叫 agent 每分鐘去輪詢一次」不同——它是被事件喚醒的,不會空轉,也不會漏掉中間發生的事。