← Tình huống

Bảng điều khiển và chỉ số trực tiếp

Biểu đồ và bộ đếm tự cập nhật, hiện giá trị mới nhất ngay khi mở trang, không cần mỗi bảng điều khiển đang mở phải hỏi liên tục.

Trang quản trị, bảng doanh số, màn hình giám sát và bảng giá cổ phiếu hay tiền mã hóa chỉ hữu ích khi con số là mới nhất. Tải lại mỗi phút nghĩa là mọi người quyết định dựa trên dữ liệu cũ, và để từng bảng điều khiển đang mở hỏi API liên tục tốn kém hơn nhiều so với đẩy một lần cập nhật tới tất cả.

Người dùng nhận được gì

  • Biểu đồ và bộ đếm tự chuyển động khi có đơn hàng, lượt đăng ký hay số đo mới.
  • Giá trị mới nhất ngay khi mở trang, không phải ô trống chờ lần cập nhật sau.
  • Màn hình treo tường vẫn trực tiếp cả ngày mà không cần tải lại.

Dùng những gì

  • Kênh cache (cache-, private-cache-), giữ sự kiện cuối cùng trong 30 phút và trao ngay cho mỗi người đăng ký mới.
  • Batch API (triggerBatch), gửi nhiều chỉ số trong một yêu cầu.
  • Phát tán miễn phí: một cập nhật được phát chỉ tính một tin nhắn, dù mười người hay mười nghìn người đang xem.
  • Webhook cache_miss, báo cho máy chủ khi một người xem mới không tìm thấy gì trong cache.

Bước 1: phát chỉ số từ backend

Gửi cập nhật khi có thay đổi, hoặc theo chu kỳ ngắn với những con số thay đổi nhanh. Gộp nhiều kênh vào một batch thì chỉ cần một lần gọi 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);

Mỗi kênh trong batch tính là một tin nhắn, nên cập nhật hai ô mỗi 5 giây là khoảng 35.000 tin nhắn một ngày. Chỉ gửi khi con số thay đổi sẽ dùng ít hơn.

Bước 2: đăng ký trong bảng điều khiển

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()));
});

Tiền tố private- nghĩa là route cấp quyền của bạn quyết định ai được xem từng bảng, chẳng hạn chỉ nhân viên, hoặc chỉ khách hàng sở hữu tài khoản đó.

Bước 3: lấp cache khi có người tới

Cho endpoint webhook nhận cache_miss, và phát giá trị hiện tại khi một người xem mở bảng điều khiển chưa có cache. Mọi người xem sau đó nhận từ cache:

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 });
  }
}

Mẹo

  • Dùng một kênh cho mỗi ô hoặc mỗi khách hàng, đừng dồn tất cả vào một kênh: người xem chỉ nhận những gì họ đang xem.
  • Gửi con số, không gửi HTML đã render, và giữ mỗi cập nhật dưới 10 KB (4 KB với gói Free).
  • Bảng điều khiển cho khách hàng (một trang phân tích trong SaaS của bạn) làm tương tự với một kênh cho mỗi tài khoản: private-cache-account-123-usage.
  • Khi điều chỉnh chu kỳ, theo dõi trực tiếp số tin nhắn và kết nối của bạn trên trang ứng dụng trong cổng khách hàng.