即時拍賣、比分與大量觀眾
把目前出價或比分同時推給成千上萬名觀眾,讓新進來的人立刻看到最新狀態,並顯示真實的「正在觀看」人數。
即時拍賣、運動比分、益智節目、限時搶購和直播留言有一個共同點:成千上萬的人在同一刻看同一件事,晚一秒就會改變結果。晚到的出價、落後轉播的比分,都會把人送去別的地方。
使用者得到什麼
- 目前出價、比分或庫存一變化就立刻看到。
- 「12,408 人正在觀看」,一個真實而且會動的數字。
- 一打開頁面就看到最新狀態,即使活動已經進行到一半。
用到的功能
- 快取頻道(
cache-),每位新進來的人立刻拿到目前的價格或比分,不必查你的資料庫。 - 大型 presence 頻道(
presence-large-),最多 100,000 名成員,提供即時人數與在場者樣本。 - 訂閱人數(
pusher:subscription_count),在公開頻道上顯示簡單的觀看人數。 - 免費扇出:一筆出價發布給 20,000 名觀眾,只算一則訊息,不是 20,000 則。
步驟 1:每次變化只發布一次
你的伺服器檢查出價或記錄比分,然後把新狀態發布給所有人:
app.post('/auctions/:id/bids', requireLogin, async (req, res) => {
const bid = await db.auctions.placeBid(req.params.id, req.user.id, req.body.amount); // rejects lower bids
await pusher.trigger(`cache-auction-${req.params.id}`, 'bid', {
amount: bid.amount,
bidder: bid.displayName,
endsAt: bid.endsAt,
});
res.json(bid);
});永遠送完整狀態(目前金額與結束時間),不要送差異:漏掉一則事件的觀眾,在下一則事件時就會恢復正確。
步驟 2:顯示給觀眾
const auction = pusher.subscribe(`cache-auction-${id}`);
auction.bind('bid', ({ amount, bidder, endsAt }) => {
price.set(amount);
feed.prepend(`${bidder} bid ${amount}`);
countdown.until(endsAt);
});訂閱後馬上會收到快取的最後一筆出價,價格永遠不會是空白。
步驟 3:觀看人數
如果只需要人數,在應用程式設定裡開啟 傳送訂閱人數,並在同一個公開頻道上綁定人數事件:
auction.bind('pusher:subscription_count', ({ subscription_count }) => watching.set(subscription_count));不寫程式也行,一行嵌入腳本可以做到同樣的事:<span data-hibira-online="cache-auction-42">0</span> watching。
如果還要顯示有誰在場,使用大型 presence 頻道與 @hibira-io/large-presence:
import { LargePresence } from '@hibira-io/large-presence';
const room = LargePresence.subscribe(pusher, `presence-large-auction-${id}`, { maxMembers: 50 });
room.on('ready', ({ count }) => audience.render(count, room.members));
room.on('change', ({ count }) => audience.render(count, room.members));人數始終精確,成員的加入與離開則每秒合併成一則小更新送達,而不是每個人一則事件。
小提醒
- 每筆出價、答案或購買都在你的伺服器上驗證。絕對不要讓用戶端自己發布活動的狀態。
- 要規劃的是連線數,而不是訊息數:20,000 名觀眾就是 20,000 個同時連線,價格取決於尖峰。請看價格。
- 像搶票開賣這種瞬間,每一兩秒發布一次庫存,而不是每賣出一張就發一次。
- 大日子之前先用真實的觀眾規模測試:用壓力測試工具開大量連線,同時在 portal 的應用程式頁面觀察。