sgcMQ 五分钟上手
这个包中附带七个原生消息客户端。MQTT 是最快跑起来的路径,因此本页就以它为例:连接到代理,订阅主题,发布消息,并看着它返回。AMQP、Kafka 和 STOMP 采用相同的双组件结构。
这个包中附带七个原生消息客户端。MQTT 是最快跑起来的路径,因此本页就以它为例:连接到代理,订阅主题,发布消息,并看着它返回。AMQP、Kafka 和 STOMP 采用相同的双组件结构。
这是最容易让人犯错的地方。协议组件负责使用 MQTT;另一个单独的客户端组件负责套接字。您只需一次赋值就能把它们连接起来。
SGC MQ 组件面板页上的 TsgcWSPClient_MQTT。它提供 Connect、Subscribe、Publish、UnSubscribe 以及十三个 MQTT 事件。
基于 WebSocket 的 MQTT 使用 TsgcWebSocketClient,基于 TCP 的普通 MQTT 使用 TsgcTCPClient。请在这个组件上设置 Host 和 Port。
MQTT.Client := WSClient;。之后,您通过设置 WSClient.Active := True 来打开连接,而不是调用协议上的某个方法。
sgcWebSocket_Protocol_MQTT_Client.pas 没有平台保护,只有一个条件性的 Windows 引入,并且该组件使用 ComponentPlatforms(0) 注册。所有目标都能编译。
版本列给出的是控制各个协议的定义,以及它在 Source/sgcVer.inc 中所在的行号。
| 项目 | 值 |
|---|---|
| IDE | Delphi 7 到 RAD Studio 13,以及 C++Builder 2007 到 13。 |
| uses 子句 | TsgcWSPClient_MQTT 使用 sgcWebSocket_Protocols,客户端使用 sgcWebSocket,TsgcWSConnection 使用 sgcWebSocket_Classes,TmqttQoS 使用 sgcWebSocket_Types。 |
| MQTT 版本 | SGC_MQTT 定义在第 717 行,位于从第 675 行延伸到第 724 行的 {$IFDEF SGC_EDT_STD} 块内。因此是 Standard 及以上版本。这些块是累加的,所以 Professional、Enterprise 和 All-Access 也包含它。 |
| 其他协议 | 都在同一个 Standard 块中:第 716 行的 SGC_STOMP,第 718 行的 SGC_AMQP,第 719 行的 SGC_AMQP1,第 720 行的 SGC_KAFKA,以及第 715 行的 SGC_WAMP。它们都不是 Enterprise 功能。 |
| 版本,独立包 | sgcMQ 产品在第 855 行定义 SGC_PACK_MQ,其自己的第 959 行到第 966 行的块会开启相同的五个协议定义。 |
| 平台 | MQTT 客户端单元上没有单元级平台保护。其 uses 子句中唯一的条件是 {$IFDEF MSWINDOWS}Windows, {$ENDIF}。 |
想要一个无需自行安装的代理来测试吗?随包附带的 MQTT 演示指向 www.esegece.com 上的公共测试代理,基于 WebSocket 的 MQTT 使用 15675 端口。
sgcMQ 包含在 sgcWebSockets 安装程序中,也作为独立的包提供。无论哪种方式,安装流程都相同。
将下载文件解压到一个文件夹,下文称之为 {$DIR}。
依次选择 Tools、Options、Library。添加 {$DIR}\source 以及与您的 IDE 对应的 lib 文件夹,例如 {$DIR}\libD13\$(Platform)。
在 {$DIR}\Packages\ 下,打开与您的 IDE 版本对应的包组。先编译运行时 .dpk,再安装设计时 dcl 包。
会出现一个名为 SGC MQ 的页面,其中包含您的版本所启用的协议客户端。在 Standard 及以上版本的构建中,会有 TsgcWSPClient_MQTT。
打开 {$DIR}\Demos\02.WebSocket_Protocols\08.MQTT_Client。下面的代码就来自这里,并且它已经指向一个在线测试代理。
把协议连接到客户端,打开连接,订阅一个主题并向它发布。消息会通过 OnMQTTPublish 返回。
uses
Classes, SysUtils,
// sgc
sgcWebSocket, sgcWebSocket_Classes, sgcWebSocket_Protocols,
sgcWebSocket_Types, sgcWebSocket_Protocol_MQTT_Client,
sgcWebSocket_Protocol_MQTT_Message;
procedure TfrmClientPROTOCOL.FormCreate(Sender: TObject);
begin
WSClient := TsgcWebSocketClient.Create(Self);
WSClient.Host := 'www.esegece.com';
WSClient.Port := 15675;
WSClient.TLS := False;
// ... attach the client to the MQTT protocol
MQTT.Client := WSClient;
// ... and THIS is what opens the connection.
// There is no Connect call on the protocol component.
WSClient.Active := True;
end;
如果要使用基于 TCP 的普通 MQTT,而不是基于 WebSocket 的 MQTT,请改为从 sgcTCP_Client_WS 创建一个 TsgcTCPClient,并让 MQTT.Client 指向它。其他一切都不变,这正是这两个组件相互独立的原因。
procedure TfrmClientPROTOCOL.btnSubscribeClick(Sender: TObject);
begin
MQTT.Subscribe('sgc/quickstart');
end;
procedure TfrmClientPROTOCOL.btnPublishClick(Sender: TObject);
begin
// topic, payload, QoS, retain
MQTT.Publish('sgc/quickstart', 'hello from Delphi',
mtqsAtLeastOnce, False);
end;
procedure TfrmClientPROTOCOL.btnUnsubscribeClick(Sender: TObject);
begin
MQTT.UnSubscribe('sgc/quickstart');
end;
Publish 返回一个 Word,即数据包标识符,并且不会等待。PublishAndWait 返回一个 Boolean,并会阻塞直到代理确认,超时时间默认为十秒。TmqttQoS 来自 sgcWebSocket_Types。
procedure TfrmClientPROTOCOL.MQTTMQTTConnect(Connection: TsgcWSConnection;
const Session: Boolean; const ReasonCode: Integer;
const ReasonName: String;
const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
memoLog.Lines.Add('#connected: ' + ReasonName);
end;
procedure TfrmClientPROTOCOL.MQTTMQTTSubscribe(Connection: TsgcWSConnection;
aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS;
SubscribeProperties: TsgcWSMQTTSUBACKProperties);
begin
memoLog.Lines.Add('#subscribed: ' + IntToStr(aPacketIdentifier));
end;
procedure TfrmClientPROTOCOL.MQTTMQTTPublish(Connection: TsgcWSConnection;
aTopic, aText: string;
PublishProperties: TsgcWSMQTTPUBLISHProperties);
begin
memoLog.Lines.Add(aTopic + ': ' + aText);
end;
这是最先需要关注的三个事件。还有另外九个,用于确认流程、断开连接和 MQTT 5.0 身份验证。请让 IDE 生成处理程序,因为参数列表很长,而且每个事件的属性对象各不相同。
这三个选项卡都来自随包附带的演示 Demos\02.WebSocket_Protocols\08.MQTT_Client\uClientMQTT.pas,其中的窗体控件已替换为字面量。在该项目中,MQTT 对象是放置在窗体上的;在代码中创建它的效果完全相同。
两个事件会告诉您代理已接受您,并且主题已生效。
OnMQTTConnect代理接受了会话。如果没有被接受,ReasonCode 和 ReasonName 会告诉您原因,这比一个断开的套接字有用得多。
OnMQTTSubscribe订阅已被批准。aCodes(一个 TsgcWSSUBACKS)携带了代理针对每个主题的回答,因此被拒绝的订阅是可见的,而不是悄无声息。
OnMQTTPublish收到了一条消息。向您刚订阅的主题发布,它会直接返回,这一次点击就能证明整条路径是通的。
在 QoS 1 和 2 下,投递会稍后通过 OnMQTTPubAck、OnMQTTPubRec、OnMQTTPubRel 和 OnMQTTPubComp 确认。如果您需要阻塞式调用,请使用 PublishAndWait。
六个问题几乎涵盖了所有失败的首次连接。
连接尚未打开。协议组件不会打开套接字,由客户端来打开。请设置 WSClient.Active := True,并在订阅之前等待 OnMQTTConnect。
MQTT.Client 从未被赋值。正是这一行把协议绑定到传输上,没有它,协议就无处可写。
在大多数代理上,基于 WebSocket 的 MQTT 和基于普通 TCP 的 MQTT 使用不同的端口。1883 和 8883 是常用的 TCP 端口,而 WebSocket 端点则完全在别处。随包附带的演示对 WebSocket 使用 15675。
没有这样的事件。代理发来的入站消息,文本通过 OnMQTTPublish 到达,如果您需要原始负载和完整的消息对象,则通过 OnMQTTPublishEx 到达。
它们是异步确认的。Publish 会立即返回数据包标识符;确认稍后通过 OnMQTTPubAck、OnMQTTPubRec、OnMQTTPubRel 或 OnMQTTPubComp 到达。如果需要阻塞式调用,请使用 PublishAndWait。
大多数代理需要客户端标识符和凭据。请在 Authentication 上设置它们,如果需要在连接时计算客户端标识符,请使用 OnMQTTBeforeConnect。
同样的双组件结构适用于包中的所有其他协议。
两个独立的客户端:0.9.1 用于 RabbitMQ 风格的交换器和队列,1.0 用于较新的线路协议。两者与客户端的连接方式都与 MQTT 相同。
一个原生的 Kafka 线路协议客户端,以及 STOMP 1.0 到 1.2,并带有针对 RabbitMQ 和 ActiveMQ 的特定代理变体。
参考页面记录了每个属性和事件。演示项目包含在下载包内,位于 Demos\02.WebSocket_Protocols 下。
参考:MQTT 客户端
TsgcWSPClient_MQTT 上的每个方法、属性和事件。
|
打开 | |
| 参考:AMQP 0.9.1 交换器、队列、绑定和消费者。 | 打开 | |
| 参考:AMQP 1.0 链路、会话和 1.0 消息模型。 | 打开 | |
| TsgcWSPClient_MQTT 组件页面 MQTT 客户端的完整说明,其余六个协议客户端也可从中链接访问。 | 打开 | |
| 协议概览 子协议组件如何附加到客户端或服务器。 | 打开 | |
| 在线帮助 自动生成的参考,始终与当前版本保持同步。 | 打开 |
相关阅读:发布并等待确认、AMQP 交换器和队列以及 Kafka 客户端。每个产品都有自己的快速入门,列在入门页面上。
TsgcWSPClient_MQTT 负责编码和解码 MQTT 数据包。TsgcWebSocketClient 或 TsgcTCPClient 负责套接字、主机、端口和 TLS 设置。一次赋值就能把它们连接起来:MQTT.Client := WSClient;。
Active := True。随包附带的演示正是这样做的。协议上也有一个 Connect 方法,但演示没有使用它,设置 Active 是所有示例所遵循的路径。
SGC_MQTT 定义在 sgcVer.inc 的第 717 行,位于从第 675 行延伸到第 724 行的 SGC_EDT_STD 块内。这就是 Standard 版本,即最低的付费层级,而这些块是累加的,因此所有更高的版本也包含它。第 716 行的 STOMP、第 718 行的 AMQP、第 719 行的 AMQP 1.0 和第 720 行的 Kafka 都在同一个块中。所有消息协议都不是 Enterprise 功能。
OnMQTTPublish,其签名是 procedure(Connection: TsgcWSConnection; aTopic, aText: String; PublishProperties: TsgcWSMQTTPUBLISHProperties)。没有名为 OnMQTTMessage 的事件。当您需要原始字节或完整的消息对象,而不是字符串时,请改为处理 OnMQTTPublishEx。
Publish 返回一个 Word,即数据包标识符。送达情况是异步确认的:在 QoS 1 下通过 OnMQTTPubAck,在 QoS 2 下通过 OnMQTTPubRec、OnMQTTPubRel 和 OnMQTTPubComp。如果您想要一个阻塞到代理确认为止的调用,请使用 PublishAndWait,它返回一个 Boolean,并接受一个默认为十秒的超时。
Publish 的第三个参数是 TmqttQoS,声明在 sgcWebSocket_Types.pas 中,成员有 mtqsAtMostOnce、mtqsAtLeastOnce、mtqsExactlyOnce 和 mtqsReserved。默认值是 mtqsAtMostOnce。Subscribe 的第二个参数采用相同的类型。
sgcWebSocket_Protocol_MQTT_Client.pas 没有单元级平台保护,其 uses 子句中唯一的条件是对 Windows 的引入,并且组件面板组件使用 ComponentPlatforms(0) 注册,因此 IDE 不会限制其目标平台。
MQTTVersion。这样 5.0 的属性对象就会生效:发出时使用 ConnectProperties,返回时使用每个事件上的属性参数,例如 OnMQTTConnect 上的 TsgcWSMQTTCONNACKProperties 和 OnMQTTPublish 上的 TsgcWSMQTTPUBLISHProperties。