跳至主内容

WebSocket 上的 AMQP 1.0

·6 分钟阅读

我们很高兴地宣布在 VMware Tanzu RabbitMQ 4.1 中支持 WebSocket 上的 AMQP 1.0。

此功能使任何基于浏览器的应用程序都能够使用 AMQP 1.0 与 RabbitMQ 进行通信,为广泛的高效基于浏览器的业务消息传递场景铺平了道路。

什么是 WebSocket?

RFC 6455 中定义的 WebSocket 是一个简单的协议,包含两个部分。

Client                                   Server
| |
|================ Part I =================|
|---- WebSocket Handshake Request ------->|
| GET /some/path HTTP/1.1 |
| Upgrade: websocket |
| Connection: Upgrade |
| Sec-WebSocket-Protocol: amqp |
| |
|<-- WebSocket Handshake Response --------|
| HTTP/1.1 101 Switching Protocols |
| Upgrade: websocket |
| Connection: Upgrade |
| Sec-WebSocket-Protocol: amqp |
| |
|================ Part II ================|
|<========= WebSocket Connection ========>|
| Full-duplex communication |
| |
|<---------- Binary Data [AMQP] --------->|
|<---------- Binary Data [AMQP] --------->|
|<---------- Binary Data [AMQP] --------->|
| ... |
| |
|----------- Close Frame ---------------->|
|<---------- Close Frame -----------------|

第一部分是握手,包括一个 HTTP 请求和响应。第二部分是数据传输:客户端和服务器之间保持一个 TCP 连接,允许任何一方随时将二进制数据推送到另一方。

在此示例中,二进制数据包含 AMQP 帧,因为客户端向服务器提出了 Sec-WebSocket-Protocol: amqp 请求,并且服务器接受了它。Sec-WebSocket-Protocol 头指定了在 WebSocket 之上分层的应用层协议。

此通信的协议栈如下所示:

+-------------------+
| AMQP | Application Layer
+-------------------+
| WebSocket |
+-------------------+
| TCP | Transport Layer
+-------------------+
| IP | Network Layer
+-------------------+
| Ethernet | Link Layer
+-------------------+

WebSocket 协议本身不强制规定应用层协议,因此具有灵活性。它可以支持任何协议,包括 STOMP 和 MQTT。

为什么选择 WebSocket?

WebSocket 具有以下优点:

  1. 浏览器兼容性:它允许基于浏览器的应用程序使用除 HTTP 之外的应用层协议。出于安全原因,浏览器限制 JavaScript 打开原始 TCP 连接以使用 AMQP 或 MQTT 等协议进行通信。WebSocket 可防止浏览器中运行的恶意 JavaScript,因此可在 WebSocket 层之上实现安全的应用层通信。
  2. 防火墙穿透:WebSocket 有助于在具有严格防火墙规则的环境中进行通信。例如,虽然端口 443 (https) 可能允许,但用于 amqps 的端口 5671 可能会被阻止。在这种情况下,可以使用端口 443 上的安全 WebSocket (wss) 连接通过 AMQP 进行通信。

现代浏览器普遍支持 WebSocket,使其成为基于 Web 的应用程序的实用选择。

RabbitMQ 中的 WebSocket

RabbitMQ 长期以来分别通过 rabbitmq_web_stomprabbitmq_web_mqtt 插件支持 WebSocket 上的 STOMPWebSocket 上的 MQTT

VMware Tanzu RabbitMQ 4.1 引入了新的 rabbitmq_web_amqp 插件,该插件符合 AMQP WebSocket 绑定委员会规范 01。此插件的操作方式与现有的 WebSocket 插件类似,它启动一个侦听器来管理 WebSocket 协议的各个方面。

以前,基于浏览器的应用程序经常因为缺乏 AMQP 支持而通过 WebSocket 连接到 RabbitMQ,使用 MQTT 或 STOMP。WebSocket 上的 AMQP 带来了以下好处:

  • 功能丰富:与专为简洁设计的 MQTT 和 STOMP 不同,AMQP 是一个专为业务消息传递设计的协议,支持更高级的功能。
  • 效率:AMQP 是二进制且高效的,而 STOMP 是面向文本的。

这使得 WebSocket 上的 AMQP 成为高效、功能丰富的基于浏览器的业务消息传递的绝佳选择。

WebSocket 代理

在此插件出现之前,一种变通方法是使用 WebSocket 代理。代理会接受来自客户端的 WebSocket 连接,并与 RabbitMQ 建立单独的 TCP 连接。虽然功能可用,但这种方法带来了缺点,例如:

  1. 额外的网络跳数带来的延迟增加。
  2. 维护每个客户端的两个 TCP 连接会增加资源使用。
  3. 部署和监控代理的运维开销。
  4. 额外的潜在故障点。

新插件通过提供直接的 WebSocket 上的 AMQP 支持消除了这些问题。

示例

RabbitMQ 包含 rabbitmq_web_stomp_examplesrabbitmq_web_mqtt_examples 插件,其中包含称为 “echo” 和 “bunny” 的基本示例。同样,VMware Tanzu RabbitMQ 4.1 引入了 rabbitmq_web_amqp_examples

WebSocket 上的 AMQP “bunny” 示例工作方式如下:

  1. rabbitmq_web_amqp_examples 插件创建了一个名为 amq.web_amqp_examples.bunny
  2. 访问 https://:15670/web-amqp-examples/bunny.html 时,该插件会提供 bunny.htmlbunny.pngrhea.js 文件。bunny.html 文件显示 bunny.png。此外,bunny.html 文件包含 JavaScript 代码,该代码从浏览器创建到 RabbitMQ 的 WebSocket 上的 AMQP 连接。
// default AMQP over WebSocket port and path in RabbitMQ
var url = "ws://" + location.hostname + ":15678/ws"
var ws = client.websocket_connect(WebSocket);
var connection = client.connect({
"connection_details":ws(url, ["amqp"]),
// Setting username without password causes rhea to use SASL mechanism ANONYMOUS.
"username": "ignored",
});

此代码段使用了 rhea.js 文件。 rhea 是一个开源 AMQP 1.0 TypeScript/JavaScript 库。可以通过在 rhea 存储库的根目录下运行以下命令来创建此单个文件。

npm install
make browserify

浏览器不仅打开了 WebSocket 上的 AMQP 连接,还创建了一个 会话 和到预先声明的流的 链接

var address = "/queues/" + stream
client.on("connection_open", function (context) {
sender = context.connection.open_sender(address);
// If we open a new brower tab, we want to see the existing drawing.
const filter = {'my-filter': amqp_types.wrap_described("first", "rabbitmq:stream-offset-spec")};
context.connection.open_receiver({source:{address: address, filter: filter}});
});

AMQP over WebSocket connection
WebSocket 上的 AMQP 连接

  1. 如果在同一 URL 打开第二个浏览器选项卡,它也会创建一个 WebSocket 上的 AMQP 连接,从同一个流发布和消费。
  2. 当你在任一浏览器选项卡上绘图时,另一个选项卡会看到实时绘图,因为两个选项卡都从同一个流消费。

Bunny Example
Bunny 示例

客户端

作为 rhea 的替代方案,您可以使用 RabbitMQ AMQP 1.0 JavaScript 库。如 原生 AMQP 1.0 博文所述,RabbitMQ 库包含 RabbitMQ 特有的功能,例如声明 交换队列绑定

总结

VMware Tanzu RabbitMQ 4.1 使浏览器能够使用 AMQP 1.0 与 RabbitMQ 进行通信。

请注意:新的 WebSocket 上的 AMQP 插件是一项闭源功能,仅在商业版 VMware Tanzu RabbitMQ 中提供。它不属于开源 RabbitMQ 发行版。

虽然这篇博文用一个有趣的兔子示例来说明了这项功能,但 AMQP 1.0 是一个为业务消息传递而构建的高效协议。可以想象一下企业级工具,如 Salesforce、Workday 或 Jira - 它们都运行在浏览器中,并受益于实时消息传递。

© . This site is unofficial and not affiliated with VMware.