Mercure-Hub: 入門指南

如何開始使用 Mercure-hub

👋 歡迎來到 Stackhero 文件!

Stackhero 提供現成的 Mercure-Hub cloud 解決方案,帶來多項好處,包括:

  • 無限制的請求和消息大小。
  • 使用 HTTPS 保護的可自定義域名(例如,https://real-time.your-company.com)。
  • 只需點擊即可輕鬆更新
  • 專用私有 VM提供的最佳性能和強大安全性
  • 可用於 🇪🇺 歐洲🇺🇸 美國

節省時間簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 Mercure-Hub cloud hosting 解決方案!

想像一下,您有一個銷售書籍的網站,並希望實時顯示可用庫存。

從後端推送數據到前端可能具有挑戰性。Mercure-hub 簡化了這個過程,讓您可以在幾分鐘內直接將數據發送到客戶的瀏覽器。最棒的是,它可以與任何編程語言一起使用,因為它利用了 HTTP 協議!

考慮一個場景,客戶正在查看 ID 為 1 的書籍。

在前端,您使用 HTML5 原生功能 Server-Sent Events (SSE) API 訂閱 Mercure-hub 上的主題 /books/1。只需大約 10 行 JavaScript 代碼,且不需要外部庫,這種方法既簡單又高效。

在後端,當一本書被購買時,您向 Mercure-hub 發送 HTTP 請求以更新庫存。例如,如果有 7 本 ID 為 1 的書籍,且用戶購買了一本,更新後的庫存變為 6。

您的後端將 { stockCount: 6 } 發送到 Mercure-hub 上的主題 /books/1,以便每個查看該書籍的用戶立即收到更新的庫存數量。這個過程只需要後端的一個 HTTP 請求和前端的幾行代碼。

這個原則可以用來從服務器推送數據到客戶端、客戶端之間,甚至服務器之間。

在客戶端(您的前端),只需使用 HTML5 SSE API 的簡單 JavaScript 代碼即可。

注意:在此示例中,訂閱者未經身份驗證。要使此示例生效,您必須在 Stackhero 儀表板上允許匿名訂閱者。

const endpoint = '<XXXXXX>.stackhero-network.com';

const url = new URL('https://' + endpoint + '/.well-known/mercure');

// 添加要監聽的主題
url.searchParams.append('topic', `https://${endpoint}/users/1234`);
url.searchParams.append('topic', `https://${endpoint}/books/1`);

const eventSource = new EventSource(url);

// 每次發布更新時調用回調函數
eventSource.onmessage = e => console.log(e);

在服務器端(您的後端),當您想要分發更新時,只需向 Mercure-hub API 發送 POST 請求。以下是使用 Node.js 以及 JsonWebTokenRequest 庫的示例:

const jwt = require('jsonwebtoken');
const request = require('request');

const endpoint = '<XXXXXX>.stackhero-network.com';
const publisherJwtKey = '<your publisher JWT key>';

// 定義要分發的數據
const data = {
  // 數據將被推送的主題
  topic: `https://${endpoint}/books/1`,

  // 要發送到主題的數據
  data: JSON.stringify({
    available: false,
    date: new Date()
  })
};

// 生成 bearer token
const bearer = jwt.sign(
  { mercure: { publish: [ data.topic ] } },
  publisherJwtKey,
  {
    expiresIn: 60, // Token 在一分鐘後過期
    noTimestamp: true // 不包括 'issued at' 時間戳以避免 "Token used before issued" 錯誤
  }
);

// 將數據發送到 Mercure-hub,以便它將更新分發給客戶端
request.post(
  {
    url: `https://${endpoint}/.well-known/mercure`,
    auth: { bearer },
    form: data
  },
  (err, res) => err ? console.error(err) : console.log(res)
);

就是這樣!您現在有一個在前端的訂閱者和一個在後端的發布者無縫協作。

如果您想測試 Mercure-hub,可以查看 https://github.com/stackhero-io/mercureHubGettingStarted 上的代碼示例。

這些工作示例包括一個簡單的前端頁面和一個 Node.js 後端服務器,展示了 Mercure 的實際運作方式。

使用 Mercure-hub 的後端和前端通信簡單示例使用 Mercure-hub 的後端和前端通信簡單示例

在之前的示例中,訂閱者未經身份驗證,您需要在 Stackhero 儀表板上允許 "匿名訂閱者"。

要驗證訂閱者,您需要使用 Stackhero 儀表板中定義的 "Subscriber JWT key" 生成 JWS (JSON Web Signature)。然後通過瀏覽器 cookies 或 authorization 標頭發送 JWS。

由於 Server-Sent Events API 不支持自定義標頭定義,因此必須使用 cookies。然而,使用 cookies 意味著您的 Mercure-hub 服務器和客戶端需要共享相同的域(或子域)。

如果您希望在不同域之間使用 SSE,請考慮允許標頭定義的 EventSource polyfill。可以在 https://github.com/Yaffle/EventSource 找到一個選項。

首先,在您的後端為客戶端生成 JWS。示例可在 backend/subscriberJwsGenerator.js 中找到。只需輸入您的訂閱者 JWT 並使用 node subscriberJwsGenerator.js 運行腳本。

然後,在前端的 frontend/subscriberWithAuthorization.html 文件中,填寫您的 endpoint 和生成的 JWS。在瀏覽器中打開該文件,Mercure-hub 現在將與身份驗證一起工作!

別忘了在 Stackhero 儀表板中取消勾選 "允許匿名訂閱者"!