MQTT 协议
VuGen 的 MQTT 协议支持使用机对机 (M2M) 和物联网 (IoT) 通信的网络测试。
关于 MQTT
MQTT 是一种为受约束的设备和低带宽、高延迟或不可靠网络而设计的简单的轻型发布/订阅消息协议,。
MQTT 是 M2M 和 IoT 通信以及带宽和电池电量极为宝贵的移动应用程序的理想选择。MQTT 致力于最大程度地减少网络带宽和设备资源要求,同时尝试确保可靠性和一定程度的交付保证。
MQTT 使用发布者-订阅者操作来进行客户端和服务器之间的通信。MQTT 服务器是控制客户端之间通信的消息代理。
客户端或“内容”可以是发布者或订阅者。
- “发布者”是发送消息的客户端。消息将转到消息代理,并指定一个主题。
- “订阅者”是接收消息的客户端。要接收有关主题的消息,订阅者必须订阅它。
创建 MQTT 脚本
您可以使用 MQTT 脚本向导为脚本生成属性,也可以使用定义的 MQTT 函数手动对其进行脚本编写。
脚本的客户端变量在“额外文件”> globals.h 文件中进行声明,可以从解决方案资源管理器访问该文件。
要创建 MQTT 脚本,请执行以下操作:
-
通过选择“新建脚本和解决方案”>“MQTT 协议”创建新脚本。
一个即用型脚本在编辑器中打开,其中使用了所有可用的 MQTT 函数。此外,“脚本向导”会在单独的对话框中自动打开。
-
按下列方法之一设计脚本:
注: 如果要创建多协议脚本,则可以将 MQTT 步骤集成到录制的 Web - HTTP/HTML 脚本中。有关详细信息,请参阅使用多协议脚本。
-
配置运行时设置。这些设置会影响 Vuser 脚本的运行方式。
-
在解决方案资源管理器中,双击“运行时设置”。
-
在“<测试名称>:运行时设置”视图中,根据需要配置运行时设置。要查看各个运行时设置的描述,请将光标悬停在运行时设置字段名称上。
-
MQTT 脚本向导
通过 MQTT 脚本向导,可以定义设置,然后在 MQTT 脚本中将其作为代码生成。
新建 MQTT 脚本时,将自动显示脚本向导 (默认设置)。您也可以通过单击 VuGen 工具栏上的“设计脚本”来打开它。(在编辑器中打开 MQTT 脚本时,可使用“设计脚本”按钮。)
UI 元素
|
描述
|
---|---|
连接设置选项卡 | |
代理 URL |
代理服务器的地址,格式为: tcp://host:port 或 ssl://host:port,其中 host 是域名、IPv4 地址或 IPv6 地址,位于方括号中。IPv6 地址示例: [2001:0db8:85a3:0000:0000:8a2e:0370:7334]。 如果未指定端口,则使用以下默认端口:
|
客户端 ID |
定义连接的客户端 ID。该字符串是网络中客户端的唯一标识符。将该字段留空则使用自动生成的 ID。 客户端标识如下:
|
身份验证设置 | 如果需要,定义用户名和密码以登录代理服务器。 |
启用 TLS | 选择是否需要通过 TLS (SSL) 进行安全通信,然后从下拉列表中选择相关的“TLS 版本”。如果选择“默认值”,则使用运行时设置中定义的版本。 |
使用客户端证书 |
选择以使用客户端证书,然后定义证书文件和私钥的路径以及密钥的密码 (如果密钥未加密,则将密码字段留空)。 |
检查连接 | 单击以检查 VuGen 是否可以使用定义的凭据成功连接到代理。如果连接成功,将显示一个绿勾;如果连接失败,将显示一个红叉。 |
针对新脚本显示向导 |
如果不希望在新建 MQTT 脚本时自动打开脚本向导,则清除该复选框。 提示: 如果脚本向导没有自动打开,则可以通过单击 VuGen 工具栏中的“设计脚本”来打开它。 |
全部清除 | 单击以清除所有选项卡中的所有设置。 |
生成代码 | 如果启用了该按钮,则单击以将相关步骤添加到脚本代码中;否则,继续前进到后续选项卡以定义可选设置。 |
客户端设置选项卡 | |
发布者/订阅者 |
为这些选项之一定义值。使用单选按钮在它们之间切换:
|
要发布的主题 | 用于发布消息的目标主题,例如: myhome/kitchen/temperature/1 。 |
负载 | 以字节格式设置要发布的消息。 |
保留消息 |
选中后,指示代理将主题中最后保留的消息及其 QoS 一起存储。每个主题仅存储一条消息,因此最后保留的消息将始终替换任何先前存储的消息。 这对于在新订阅者订阅主题时向其提供最新状态非常有用,因此他们无需等待下一个状态更新。 |
服务质量 |
所需的服务质量 (QoS)。例如,如果在 QoS = 0 的情况下失去连接,则客户端在重新连接后不会尝试再次发布,并且脚本输出中将显示警告。 值为 0 到 2 和默认值 (在运行时设置中定义)。 |
要订阅的主题 |
用于使客户端订阅一个主题或一组主题 (通过使用通配符)。代理自动发送有关这些主题的消息。主题可以包含通配符。 示例:
使用在运行时设置中定义的默认 QoS。 |
Last Will 和 Testament 选项卡 | |
主题 | 定义目标主题,以将某客户端非正常断开连接的信息通知给其他客户端。 |
负载 | 设置客户端意外断开连接时代理发送给指定主题订阅者的消息。 |
保留消息 | 选中后,指示代理将最后保留的消息存储在此主题中。每个主题仅存储一条消息,因此最后保留的消息将始终替换任何先前存储的消息。 |
您可以使用 MQTT 脚本向导为现有客户端 (在脚本中已有连接的客户端) 定义其他属性。客户端由向导中提供的“客户端 ID”定义。
可能的其他属性有:
-
发布者。一个客户端可以有多个发布者。如果为现有客户端创建了发布者,则新发布者添加到相应客户端的 Actions.c 文件中。
-
订阅者。客户端一次只能订阅一个主题。如果为现有客户端创建了订阅者,则代码生成将验证现有客户端是否已经订阅。如果它有一个订阅者,则忽略向导中的订阅者。否则,将订阅者添加到 vuser_init.c 文件中的
client_settings()
函数中,并在 vuser_end.c 文件中相应的客户端断开连接之前添加相应的取消订阅。 -
Last Will 和 Testament。一个客户端只能有一条 Last Will 和 Testament (LWT) 消息。如果为现有客户端创建了 LWT 消息,则代码生成将验证现有客户端是否已有 LWT。如果已有,则忽略向导中的 LWT 消息。如果没有,则新的 LWT 函数添加到 vuser_init.c 文件的
client_settings()
函数中的相应客户端。
使用多协议脚本
您可以测试脚本同时使用以下两个协议的场景:
-
MQTT 在客户端和代理之间进行通信
-
Web - HTTP/HTML 以在代理和 Web 应用程序之间进行通信
您可以通过在 Web 应用程序上录制步骤来准备脚本。然后根据需要手动添加 MQTT 步骤。使用多协议脚本时不包括预填充的 MQTT 脚本,但是您可以从即用型 MQTT 脚本模板中复制/粘贴。
要启用支持,请执行以下操作:
-
创建一个包含 MQTT 和 Web - HTTP/HTML 的多协议脚本。有关详细信息,请参阅创建新脚本对话框。
-
录制 Web 脚本。
注: 录制 Web 脚本会覆盖 globals.h,从而移除对 MQTT 步骤的默认支持。
-
恢复对 MQTT 步骤的支持:
-
打开 globals.h (位于解决方案资源管理器中的“额外文件”下)。
-
将 #include "MqttApi.h" 添加到 Include Files 部分。
-
-
将 MQTT 步骤添加到脚本中。
多协议脚本示例
Action() { MQTT client; client = mqtt_create(); mqtt_set_client_id(client, "myclientid"); lr_start_transaction("connect_MQTT"); mqtt_connect(client, "tcp://mymachine:1883"); lr_end_transaction("connect_MQTT", LR_AUTO); lr_start_transaction("navigate_Web"); // your recorded web code here lr_end_transaction("navigate_Web", LR_AUTO); mqtt_publish(client, "topic/subtopic", "payload", MQTT_AUTO, MQTT_DEFAULT, MQTT_NORETAIN); mqtt_disconnect(client); return 0; }
即用型 MQTT 脚本模板
默认的单协议 MQTT 脚本包含预先填充带注释步骤的操作 (如下所示)。
在使用多协议脚本时,首先要在 Web 应用程序上录制步骤。然后根据需要添加 MQTT 步骤。可以从下面的模板复制/粘贴相关步骤。
有关这些函数的详细信息,请参阅函数参考。
vuser_init
vuser_init() { /* Declared in "globals.h" */ client = mqtt_create(); /* Optional connection settings */ // mqtt_set_client_id(client, "<insert Client ID>"); // mqtt_set_credentials(client, "<username placeholder>", "<password placeholder>"); // mqtt_set_lwt(client, "<topic>", "<sample lwt payload>", MQTT_AUTO, MQTT_DEFAULT, MQTT_RETAIN); /* Optional SSL/TLS settings, applicable for SSL/TLS connections only */ // mqtt_set_tls_certificate(client, "<path to a certificate file, e.g. cert.pem>", "<path to a private key file, e.g. key.pem>", "<password for the private key>"); // mqtt_set_tls_parameters(client, MQTT_TLS_DEFAULT, MQTT_DEFAULT_CIPHERS); /* Connect to an MQTT broker */ mqtt_connect(client, "tcp://<enter an MQTT broker host name>"); /* Uncomment the following if implementing the "subscriber" logic */ // mqtt_subscribe(client, "<topic>"); return 0; }
操作
Action() { /* Uncomment the following if implementing the "subscriber" logic.Make sure to also uncomment subscribe/unsubscribe in vuser_init/end.c */ // /* Option 1: Wait for messages, then handle their contents */ // size_t messageCount = mqtt_await_messages(client, MQTT_DEFAULT); // size_t i = 0; // for ( ; i < messageCount; i++) // { // MQTT_MESSAGE m = mqtt_read_inbox(client); // const char* p = mqtt_get_payload(m); // const char* t = mqtt_get_topic(m); // size_t l = mqtt_get_length(m); // ... do something meaningful with the message // ... for instance, print received message information (assuming its payload is not binary data) // lr_message("received message with size %d from %s", l, t); // lr_message("payload %.*s", l, p); // // mqtt_free_message(m); // } /* Option 2: Wait for messages, then clear Inbox (if their handling is not needed) */ // mqtt_await_messages(client, MQTT_DEFAULT); // mqtt_clear_inbox(client); /* Uncomment the following if implementing the "publisher" logic */ // mqtt_publish(client, "<topic>", "<payload>", MQTT_AUTO, MQTT_DEFAULT, MQTT_RETAIN); return 0; }
vuser_end
vuser_end() { /* Uncomment the following if implementing the "subscriber" logic */ // mqtt_unsubscribe(client, "<topic>"); /* Disconnect from the MQTT broker */ mqtt_disconnect(client); return 0; }