你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

快速入门:使用 Azure CLI 在事件网格命名空间上发布和订阅 MQTT 消息

Azure 事件网格的 MQTT 中转站功能支持使用 MQTT 协议进行消息传递。 客户端(包括设备和云应用程序)可以通过灵活的分层主题发布和订阅 MQTT 消息,以实现大规模广播以及命令和控制等方案。

在本文中,我们使用 Azure CLI 来执行以下操作:

  • 创建事件网格命名空间并启用 MQTT 代理。
  • 创建子资源,例如客户端、客户端组和主题空间。
  • 为客户端授予发布和订阅主题空间的访问权限。
  • 发布和接收 MQTT 消息。

如果没有 Azure 订阅,请在开始之前创建一个 Azure 免费帐户

先决条件

  • 如果你不熟悉事件网格,请在开始本教程之前通读事件网格概述
  • 根据注册事件网格资源提供程序中的步骤注册事件网格资源提供程序。
  • 确保已在防火墙中打开端口 8883。 本教程中的示例使用 MQTT 协议,该协议通过端口 8883 进行通信。 在某些公司和教育网络环境中,此端口可能被阻止。
  • Azure Cloud Shell 中使用 Bash 环境。 有关详细信息,请参阅 Azure Cloud Shell 中的 Bash 快速入门
  • 如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅在 Docker 容器中运行 Azure CLI
  • 如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录
  • 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展
  • 运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade
  • 本文需要 2.53.1 或更高版本的 Azure CLI。 如果你使用的是 Azure Cloud Shell,则表示已安装最新版本。
  • 需要使用一个 X.509 客户端证书生成指纹并对客户端连接进行身份验证。
  • 查看事件网格命名空间 CLI 文档

生成示例客户端证书和指纹

如果你没有证书,可以使用 step CLI 创建一个示例证书。 考虑手动安装适用于 Windows 的版本。

使用 step CLI 成功进行安装后,请在用户配置文件文件夹 (Win+R type %USERPROFILE%) 中打开命令提示符。

  1. 要创建根证书和中间证书,请运行以下命令。 请记住密码,需要在下一步中使用它。

    step ca init --deployment-type standalone --name MqttAppSamplesCA --dns localhost --address 127.0.0.1:443 --provisioner MqttAppSamplesCAProvisioner
    
  2. 使用生成的证书颁发机构 (CA) 文件为客户端创建证书。 确保在命令中使用正确的证书和机密文件路径。

    step certificate create client1-authnID client1-authnID.pem client1-authnID.key --ca .step/certs/intermediate_ca.crt --ca-key .step/secrets/intermediate_ca_key --no-password --insecure --not-after 2400h
    
  3. 若要查看指纹,请运行 step 命令。

    step certificate fingerprint client1-authnID.pem
    

创建命名空间

使用该命令创建命名空间。 使用你的资源组和命名空间名称更新该命令。

az eventgrid namespace create -g {Resource Group} -n {Namespace Name} --topic-spaces-configuration "{state:Enabled}"

为了简化过程,本快速入门使用最少量的属性来创建命名空间。 有关在向导的其他页上配置网络、安全性和其他设置的详细步骤,请参阅创建和管理命名空间

创建客户端

使用该命令创建客户端。 使用你的资源组和命名空间名称更新该命令。

az eventgrid namespace client create -g {Resource Group} --namespace-name {Namespace Name} -n {Client Name} --authentication-name client1-authnID --client-certificate-authentication "{validationScheme:ThumbprintMatch,allowed-thumbprints:[Client Thumbprint]}"
  • 为了简化过程,本快速入门使用“指纹匹配”进行身份验证。 有关如何使用 X.509 CA 证书链进行客户端身份验证的步骤,请参阅使用证书链进行客户端身份验证
  • 对于本练习,我们将使用默认的 $all client 组,其中包含命名空间中的所有客户端。 若要详细了解如何使用客户端属性创建自定义客户端组,请参阅客户端组

创建主题空间

使用该命令创建主题空间。 使用你的资源组、命名空间名称和主题空间名称更新该命令。

az eventgrid namespace topic-space create -g {Resource Group} --namespace-name {Namespace Name} -n {Topicspace Name} --topic-templates ['contosotopics/topic1']

创建权限绑定

使用 az eventgrid 命令为发布者权限创建第一个权限绑定。 使用你的资源组、命名空间名称和权限绑定名称更新该命令。

az eventgrid namespace permission-binding create -g {Resource Group} --namespace-name {Namespace Name} -n {Permission Binding Name} --client-group-name '$all' --permission publisher --topic-space-name {Topicspace Name}

使用该命令创建第二个权限绑定。 使用你的资源组、命名空间名称和权限绑定名称更新该命令。 此权限绑定用于订阅服务器。

az eventgrid namespace permission-binding create -g {Resource Group} --namespace-name {Namespace Name} -n {Name of second Permission Binding} --client-group-name '$all' --permission publisher --topic-space-name {Topicspace Name}

发布和订阅 MQTT 消息

以下示例代码是一个简单的 .NET 发布服务器,它尝试连接并发布到命名空间,并订阅 MQTT 主题。 可以使用代码根据要求进行修改,并在 Visual Studio 或你偏好的任何工具中运行该代码。

需要从 NuGet 安装 MQTTnet 包(版本 4.1.4.563)才能运行此代码。 (在 Visual Studio 中,右键单击解决方案资源管理器中的项目名称,转到“管理 NuGet 包”,搜索“MQTTnet”。选择“MQTTnet包”并进行安装。)

注意

下面的示例代码仅用于演示,不用于生产。

用于连接客户端、在主题上发布和订阅 MQTT 消息的示例 C# 代码

重要

请根据客户端证书文件的位置更新客户端证书和密钥 pem 文件路径。 此外,请确保客户端身份验证名称和主题信息与配置匹配。

using MQTTnet.Client;
using MQTTnet;
using System.Security.Cryptography.X509Certificates;

string hostname = "{Your Event Grid namespace MQTT hostname}";
string clientId = "client1-session1";  //client ID can be the session identifier.  A client can have multiple sessions using username and clientId.
string x509_pem = @" client certificate cer.pem file path\client.cer.pem";  //Provide your client certificate .cer.pem file path
string x509_key = @"client certificate key.pem file path\client.key.pem";  //Provide your client certificate .key.pem file path

var certificate = new X509Certificate2(X509Certificate2.CreateFromPemFile(x509_pem, x509_key).Export(X509ContentType.Pkcs12));

var mqttClient = new MqttFactory().CreateMqttClient();

var connAck = await mqttClient!.ConnectAsync(new MqttClientOptionsBuilder()
    .WithTcpServer(hostname, 8883)
    .WithClientId(clientId)
    .WithCredentials("client1-authnID", "")  //use client authentication name in the username
    .WithTls(new MqttClientOptionsBuilderTlsParameters()
    {
        UseTls = true,
        Certificates = new X509Certificate2Collection(certificate)
    })

    .Build());

Console.WriteLine($"Client Connected: {mqttClient.IsConnected} with CONNACK: {connAck.ResultCode}");

mqttClient.ApplicationMessageReceivedAsync += async m => await Console.Out.WriteAsync($"Received message on topic: '{m.ApplicationMessage.Topic}' with content: '{m.ApplicationMessage.ConvertPayloadToString()}'\n\n");

var suback = await mqttClient.SubscribeAsync("contosotopics/topic1");
suback.Items.ToList().ForEach(s => Console.WriteLine($"subscribed to '{s.TopicFilter.Topic}' with '{s.ResultCode}'"));

while (true)
{
    var puback = await mqttClient.PublishStringAsync("contosotopics/topic1", "hello world!");
    Console.WriteLine(puback.ReasonString);
    await Task.Delay(1000);
}

可为多个客户端复制并修改上述代码,以便在客户端中进行发布和订阅。

后续步骤