Delphi TMSMQTT使用笔记
<p>服务端用的是 mosquitto ,下载地址https://mosquitto.org/download/</p><p>安装完成后需要配置</p>
<p>找到安装目录:mosquitto.conf,打开后修改 allow_anonymous false(禁止匿名登录),password_file D:\Program Files\mosquitto\pwfile.example(密码存放位置)</p>
<p>创建新用户,安装目录下执行 mosquitto_passwd <span class="hljs-operator">-<span class="hljs-built_in">c pwfile.example 用户名<span class="hljs-number">1 然后输入密码</span></span></span></p>
<p><span class="hljs-operator"><span class="hljs-built_in"><span class="hljs-number">主要记录Delphi开发过程,mosquitto 具体使用及配置自行百度</span></span></span></p>
<p><span class="hljs-operator"><span class="hljs-built_in"><span class="hljs-number">界面布局如下</span></span></span></p>
<p><img src="https://img2024.cnblogs.com/blog/911540/202405/911540-20240519005612137-1519754410.png" alt="" loading="lazy"></p>
<p> </p>
<p>当使用 TMSMQTTClient1 组件进行 MQTT 通信时,常用属性的详细设置如下:</p>
<ul>
<li>BrokerHostName:设置为 MQTT 服务器的主机名或 IP 地址,例如 "mqtt.example.com"。</li>
<li>BrokerPort:设置为 MQTT 服务器的端口号,通常默认为 1883 或 8883(如果使用了 SSL 加密)。</li>
<li>Credentials.Username:设置为连接 MQTT 服务器所需的用户名。如果服务器不需要用户名认证,可以将其留空。</li>
<li>Credentials.Password:设置为连接 MQTT 服务器所需的密码。如果服务器不需要密码认证,可以将其留空。</li>
<li>ClientID:设置为客户端的唯一标识符,通常可以使用设备的序列号或其他唯一标识符。</li>
<li>LastWillSettings.QoS:设置遗嘱消息的服务质量等级,可选择 qosAtLeastOnce、qosAtMostOnce 或 qosExactlyOnce,取决于消息的重要性和可靠性要求。</li>
<li>LastWillSettings.Retain:设置为 true 或 false,指定是否将遗嘱消息保留在服务器上,以便订阅者在客户端断开连接后收到该消息。</li>
<li>KeepAliveInterval:设置客户端与服务器之间的通信心跳间隔时间,通常以秒为单位,例如 60 表示每 60 秒发送一次心跳。</li>
<li>CleanSession:设置为 true 或 false,指示服务器在客户端断开连接时是否清除会话信息。一般情况下,如果设置为 false,服务器会保存客户端的会话信息,以便客户端重新连接后可以恢复之前的订阅状态和会话信息。</li>
<li>OnConnect:设置连接成功时触发的事件处理程序,可以在此事件中执行连接后的操作。</li>
<li>OnDisconnect:设置断开连接时触发的事件处理程序,可以在此事件中处理连接断开后的清理工作。</li>
<li>OnMessage:设置接收到消息时触发的事件处理程序,可以在此事件中处理接收到的 MQTT 消息。</li>
</ul>
<p>TMSMQTTLogger1可以用于记录以下内容:</p>
<ul>
<li>连接建立和断开的事件;</li>
<li>客户端订阅和取消订阅主题的操作;</li>
<li>接收到的消息内容;</li>
<li>发布消息的操作;</li>
<li>错误和异常信息的记录。</li>
</ul>
<p>连接按钮事件如下,详情见中文注释</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置MQTT服务器主机名和端口</span>
TMSMQTTClient1.BrokerHostName :=<span style="color: rgba(0, 0, 0, 1)"> Edit1.Text;
TMSMQTTClient1.BrokerPort :</span>=<span style="color: rgba(0, 0, 0, 1)"> StrToInt(Edit2.Text);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置用户名和密码</span>
TMSMQTTClient1.Credentials.Username :=<span style="color: rgba(0, 0, 0, 1)"> Edit3.Text;
TMSMQTTClient1.Credentials.Password :</span>=<span style="color: rgba(0, 0, 0, 1)"> Edit4.Text;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置客户端ID</span>
TMSMQTTClient1.ClientID :=<span style="color: rgba(0, 0, 0, 1)"> Edit5.Text;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置遗嘱消息的服务质量等级</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> ComboBox1.Text = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">qosAtLeastOnce</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
TMSMQTTClient1.LastWillSettings.QoS :</span>=<span style="color: rgba(0, 0, 0, 1)"> qosAtLeastOnce
</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ComboBox1.Text = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">qosAtMostOnce</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
TMSMQTTClient1.LastWillSettings.QoS :</span>=<span style="color: rgba(0, 0, 0, 1)"> qosAtMostOnce
</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ComboBox1.Text = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">qosExactlyOnce</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
TMSMQTTClient1.LastWillSettings.QoS :</span>=<span style="color: rgba(0, 0, 0, 1)"> qosExactlyOnce
</span><span style="color: rgba(0, 0, 255, 1)">else</span> <span style="color: rgba(0, 0, 255, 1)">if</span> ComboBox1.Text = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">qosRESERVED</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
TMSMQTTClient1.LastWillSettings.QoS :</span>=<span style="color: rgba(0, 0, 0, 1)"> qosRESERVED;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置遗嘱消息的保留标志</span>
TMSMQTTClient1.LastWillSettings.Retain :=<span style="color: rgba(0, 0, 0, 1)"> CheckBox1.Checked;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 连接到MQTT服务器</span>
TMSMQTTClient1.Connect();</pre>
</div>
<p>连接后只有订阅相同Topic的才能收到内容,所以连接后需要先订阅,订阅按钮如下</p>
<div class="cnblogs_code">
<pre>TMSMQTTClient1.Subscribe(edit7.Text);</pre>
</div>
<p>状态改变后显示目前连接状态</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span> TMQTTClient.TMSMQTTClient1ConnectedStatusChanged(ASender: TObject; <span style="color: rgba(0, 0, 255, 1)">const</span><span style="color: rgba(0, 0, 0, 1)"> AConnected: Boolean; AStatus: TTMSMQTTConnectionStatus);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">case</span> AStatus <span style="color: rgba(0, 0, 255, 1)">of</span><span style="color: rgba(0, 0, 0, 1)">
csConnectionLost:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">连接丢失</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csAuthenticating:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">正在进行身份验证</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csConnecting:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">连接中</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csConnected:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">已连接</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csNotConnected:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">未连接状态</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csReconnecting:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">重新连接中</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
csDisconnecting:
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">断开连接中</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>具体状态内容如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">csNotConnected:未连接状态
csConnectionRejected_InvalidProtocolVersion:连接被拒绝,协议版本无效
csConnectionRejected_InvalidIdentifier:连接被拒绝,标识符无效
csConnectionRejected_ServerUnavailable:连接被拒绝,服务器不可用
csConnectionRejected_InvalidCredentials:连接被拒绝,凭据无效
csConnectionRejected_ClientNotAuthorized:连接被拒绝,客户端未授权
csConnectionRejected_UnspecifiedError:连接被拒绝,未指定的错误
csConnectionRejected_MalformedPacket:连接被拒绝,数据包格式错误
csConnectionRejected_ProtocolError:连接被拒绝,协议错误
csConnectionRejected_ImplementationSpecificError:连接被拒绝,特定实现的错误
csConnectionRejected_ServerBusy:连接被拒绝,服务器繁忙
csConnectionRejected_Banned:连接被拒绝,被禁止
csConnectionRejected_BadAuthenticationMethod:连接被拒绝,身份验证方法错误
csConnectionRejected_TopicNameInvalid:连接被拒绝,主题名无效
csConnectionRejected_PacketTooLarge:连接被拒绝,数据包太大
csConnectionRejected_QuotaExceeded:连接被拒绝,超出配额
csConnectionRejected_PayloadFormatInvalid:连接被拒绝,负载格式无效
csConnectionRejected_RetainNotSupported:连接被拒绝,不支持retain
csConnectionRejected_QoSNotSupported:连接被拒绝,不支持QoS
csConnectionRejected_UseAnotherServer:连接被拒绝,使用其他服务器
csConnectionRejected_ServerMoved:连接被拒绝,服务器已移动
csConnectionRejected_ConnectionRateExceeded:连接被拒绝,连接速率超过限制
csConnectionLost:连接丢失
csAuthenticating:正在进行身份验证
csConnecting:连接中
csReconnecting:重新连接中
csConnected:已连接
csDisconnecting:断开连接中</span></pre>
</div>
<p>发布消息代码如下</p>
<div class="cnblogs_code">
<pre>TMSMQTTClient1.Publish(Edit6.Text, Memo1.Text);</pre>
</div>
<p>订阅后收到的消息,在onPublishReceived事件中,可以根据收到的消息内容做自己想做的事,代码如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span> TMQTTClient.TMSMQTTClient1PublishReceived(ASender: TObject; APacketID: Word; ATopic: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">; APayload: TBytes);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">PublishReceived:</span><span style="color: rgba(128, 0, 0, 1)">'</span> +<span style="color: rgba(0, 0, 0, 1)"> TEncoding.UTF8.GetString(APayload));
</span><span style="color: rgba(0, 0, 255, 1)">if</span> TEncoding.UTF8.GetString(APayload) = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Hello</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Say hello to you in the opposite direction!</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> TEncoding.UTF8.GetString(APayload) = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">你好</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
Memo3.Lines.Add(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">对方向你问好!</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>记录TMSMQTTClient状态事件在TMSMQTTLogger1的onLog中,代码如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span> TMQTTClient.TMSMQTTLogger1Log(Sender: TObject; ALevel: TTMSMQTTLogLevel; AMessage: <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
Memo3.Lines.Add(AMessage);
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;</pre>
</div>
<p>界面效果如下</p>
<p><img src="https://img2024.cnblogs.com/blog/911540/202405/911540-20240519005525518-1879459064.png" alt="" loading="lazy"></p>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<p>本文来自博客园,作者:liessay,转载请注明原文链接:https://www.cnblogs.com/liessay/p/18199981</p><br><br>
来源:https://www.cnblogs.com/liessay/p/18199981
頁:
[1]