Mercure-Hub: 入门指南

如何开始使用 Mercure-hub

👋 欢迎使用 Stackhero 文档!

Stackhero 提供现成的 Mercure-Hub 云 解决方案,具有多种优势,包括:

  • 无限制的请求和消息大小。
  • 使用 HTTPS 保护的可定制域名(例如,https://real-time.your-company.com)。
  • 只需点击即可轻松更新
  • 专用私有 VM提供的最佳性能和强大安全性
  • 🇪🇺 欧洲🇺🇸 美国均可使用。

节省时间简化您的生活:只需 5 分钟即可试用 Stackhero 的 Mercure-Hub 云托管 解决方案!

想象一下,您有一个销售书籍的网站,并希望实时显示可用库存。

从后端向前端推送数据可能具有挑战性。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 令牌
const bearer = jwt.sign(
  { mercure: { publish: [ data.topic ] } },
  publisherJwtKey,
  {
    expiresIn: 60, // 令牌在一分钟后过期
    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)。然后通过浏览器 cookie 或 authorization 头发送 JWS。

由于 Server-Sent Events API 不支持自定义头定义,因此必须使用 cookie。然而,使用 cookie 意味着您的 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 仪表板中取消选中“允许匿名订阅者”!