← 使用情境

即時儀表板與指標

會自己更新的圖表與計數器,頁面一打開就顯示最新數值,不必讓每個開著的儀表板去輪詢。

管理後台、銷售儀表板、監控畫面、股票或加密貨幣報價,只有數字是最新的才有用。每分鐘重新整理一次,代表大家根據舊資料做決定;讓每個開著的儀表板去輪詢 API,成本也遠高於把一次更新推給所有人。

使用者得到什麼

  • 訂單、註冊或讀數一進來,圖表與計數器就自己動起來。
  • 頁面一打開就看到最新數值,不會在下次更新前一片空白。
  • 掛在牆上的螢幕整天保持即時,不必重新載入。

用到的功能

  • 快取頻道(cache-、private-cache-),保留最後一則事件 30 分鐘,並立刻交給每位新訂閱者。
  • 批次 API(triggerBatch),一次請求送出多項指標。
  • 免費扇出:不論有十個人還是一萬個人在看,一次發布的更新都只算一則訊息。
  • cache_miss webhook,在新觀看者發現沒有快取時通知你的伺服器。

步驟 1:從後端發布指標

數字有變化時送出更新;變化很快的數字則用短間隔定時送。把多個頻道合成一個批次,只要一次 HTTP 呼叫:

setInterval(async () => {
  const stats = await metrics.snapshot();
  await pusher.triggerBatch([
    { channel: 'private-cache-dash-sales', name: 'update', data: { revenue: stats.revenue, orders: stats.orders } },
    { channel: 'private-cache-dash-signups', name: 'update', data: { today: stats.signups } },
  ]);
}, 5000);

批次裡的每個頻道各算一則訊息,所以兩個區塊每 5 秒更新一次,一天大約是 35,000 則訊息。只在數字改變時才送,就能用得更少。

步驟 2:在儀表板裡訂閱

const sales = pusher.subscribe('private-cache-dash-sales');
sales.bind('update', ({ revenue, orders }) => {
  revenueTile.set(revenue);
  ordersChart.push(orders);
});

// Nothing published in the last 30 minutes: load the value from your API once
sales.bind('pusher:cache_miss', async () => {
  revenueTile.set(await fetch('/api/stats/revenue').then((r) => r.json()));
});

private- 前綴代表由你的授權路由決定誰能看每個儀表板,例如只限員工,或只限該帳號所屬的客戶。

步驟 3:有人進來時補上快取

讓 webhook 端點訂閱 cache_miss,當觀看者打開一個沒有快取的儀表板時,發布目前的數值。之後的每位觀看者都直接從快取拿到:

for (const e of webhook.getEvents()) {
  if (e.name === 'cache_miss' && e.channel === 'private-cache-dash-sales') {
    const s = await metrics.snapshot();
    await pusher.trigger(e.channel, 'update', { revenue: s.revenue, orders: s.orders });
  }
}

小提醒

  • 每個區塊或每位客戶用一個頻道,不要全部塞進同一個頻道:觀看者只會收到自己在看的內容。
  • 傳數字,不要傳渲染好的 HTML,每次更新保持在 10 KB 以下(Free 方案為 4 KB)。
  • 給客戶看的儀表板(例如你 SaaS 裡的分析頁)做法相同,每個帳號一個頻道:private-cache-account-123-usage。
  • 調整間隔時,可以在 portal 的應用程式頁面即時查看自己的訊息數與連線數。