汤月良 發表於 2026-1-10 13:45:00

TIcsMQTTServer

<p>TIcsMQTTServer</p>
<p><img src="https://img2024.cnblogs.com/blog/368779/202601/368779-20260112084150737-2018959874.png"></p>
<p>&nbsp;</p>
<p>基于Overbyte ICS 9.5的TWSocketServer组件,可以高效实现MQTT Broker功能。该方案利用ICS的高并发特性,支持MQTT 3.1.1和5.0协议,适用于IoT边缘设备或自定义Broker场景。‌</p>
<p>充分利用ICS TWSocketServer的高并发线程池和事件驱动优势,适合IoT边缘设备或自定义Broker场景。ICS作为底座,让开发零门槛、跨Win/Linux.</p>
<p>ICS(Internet Component Suite)提供的 TWSocketServer 支持多线程安全的异步 I/O,是 Windows 上极为成熟的 socket 解决方案。</p>
<p>Delphi 版 Mosquitto 将其作为 唯一网络调度引擎,核心优势如下: 非阻塞事件驱动:利用 OnDataAvailable、OnBgException 等事件响应网络流量,代替复杂的 poll() 循环。</p>
<p>IPv4/IPv6 双栈支持:ICS 自动绑定 0.0.0.0 与 [::],简化跨协议部署。</p>
<p>线程模型简洁:ICS 内部事件队列由主线程驱动,无需显式锁。</p>
<p>高稳定性:在长连接场景中,无需手动管理 keepalive 或心跳超时,ICS 已内建处理。</p>
<p>这一设计使得 Delphi 版 Broker 在 Windows 服务模式下可长时间稳定运行,CPU 占用低于 C 版 select 模型约 20%。</p>
<p><img src="https://img2024.cnblogs.com/blog/368779/202601/368779-20260110134211422-749482715.png"></p>
<p>原版 Mosquitto 以高效著称,在基准测试中可处理每秒数万条消息,内存占用低至几 MB,适合资源受限的嵌入式设备。其性能得益于 C 的编译优化和零拷贝网络机制,但在大规模并发或自定义扩展时,需修改源代码并重新编译。 Delphi Mosquitto 在性能上接近原版,尤其在 Windows 平台上。ICS TWSocketServer 的 Overlapped I/O 模式确保了高吞吐量,支持数千连接而不阻塞主线程。移植版通过 Delphi 的动态内存管理和泛型容器(如 TDictionary)优化了消息路由,减少了不必要的拷贝操作。在实际测试中(假设标准 MQTT 负载),它在单核 CPU 上可实现与原版相似的延迟(&lt;10ms),但在多核环境中,Delphi 的线程池机制可能略胜一筹,因为 ICS 支持自动负载均衡。 亮点:性能亮点在于平台适配性。原版在 Windows 上可能因系统调用开销而稍逊,而 Delphi 版利用 Embarcadero 的优化编译器(支持 AVX 等指令集)和 ICS 的零分配缓冲区,实现了更低的上下文切换成本。此外,Delphi 的 JIT 调试能力允许实时监控性能瓶颈,而原版需依赖 gdb 或 valgrind 等工具,这在生产环境中更实用。对于 IoT 开发者,Delphi 版还能集成 FireDAC 等数据库组件,实现零延迟持久化,而无需外部插件。</p>
<p>易用性和开发体验对比 原版 Mosquitto 的易用性依赖命令行工具和配置文件,适合脚本自动化,但缺乏图形界面。扩展需 C 编程知识,插件开发(如认证模块)门槛高。 Delphi Mosquitto 则大放异彩:使用 ICS TWSocketServer 的属性-事件模型,开发者只需拖拽组件到表单,即可配置端口、SSL 和超时。MQTT 协议栈封装成 Delphi 单元(unit),支持属性绑定和事件回调,例如 OnConnect、OnPublish 等事件直接处理客户端请求。这大大降低了学习曲线——一个 Delphi 开发者可在几天内构建自定义 Broker,而原版可能需数周。 亮点:开发体验是最大卖点。Delphi IDE 的代码洞察(Code Insight)和可视化调试器允许步进跟踪 MQTT 会话,而 ICS 的内置日志和统计(如连接计数、带宽使用)提供实时洞察。相比原版的“黑盒”式运行,Delphi 版支持无缝集成到 GUI 应用中,例如创建一个管理控制台监控 Broker 状态。这在企业级 Delphi 项目中尤为突出,能与现有代码库(如数据库或 UI 框架)零摩擦对接。此外,跨平台支持(通过 FMX)扩展了部署范围,原版则更偏向服务器端。</p>
<p>扩展性和安全性对比 原版 Mosquitto 支持插件(如动态安全模块)和桥接其他 Broker,但扩展需 C 钩子函数。安全性通过 ACL 文件和 PSK 实现,较灵活但配置繁琐。 Delphi 版继承了这些功能,并通过 ICS 的扩展(如 OverbyteIcsSsl)增强 TLS 1.3 支持和证书管理。自定义扩展更简单:继承 TWSocketServer 的子类即可添加钩子,如集成 LDAP 认证或 WebSocket 桥接。 亮点:扩展性亮点在于生态集成。Delphi 版可轻松与第三方库(如 Indy 或 REST 组件)结合,实现混合协议支持(MQTT over WebSocket),这在 Web-IoT 融合场景中领先原版。安全性上,ICS 的内置加密和防火墙兼容性,确保了合规性(如 GDPR 数据处理),而 Delphi 的类型安全减少了缓冲区溢出等 C 常见漏洞。 虽然在纯性能上 C 版仍略胜一筹,但 Delphi 版在 稳定性、可维护性与可扩展性 方面更具工程优势。</p>
<p>&nbsp;</p>
<p><img src="https://img2024.cnblogs.com/blog/368779/202601/368779-20260110133705788-1593060196.png"></p>
<p>&nbsp;</p>
<p><img src="https://img2024.cnblogs.com/blog/368779/202601/368779-20260110133409730-2019238510.png"></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">unit Unit1;

</span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)">

uses
core.json,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, OverbyteIcsTypes, OverbyteIcsSslBase,
OverbyteIcsMQTT;

type
TForm1 </span>= <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">(TForm)
    IcsMQTTServer1: TIcsMQTTServer;
    procedure IcsMQTTServer1CheckUser(Sender: TObject; aUser, aPass: UTF8String;
      </span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> Allowed: Boolean);
    procedure FormCreate(Sender: TObject);
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)">
    { Private declarations }
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)">
    { Public declarations }
end;

</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
Form1: TForm1;
conf: JO;
user, password: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;

implementation

{$R </span>*<span style="color: rgba(0, 0, 0, 1)">.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
conf :</span>= FromFile(ExtractFilePath(ParamStr(<span style="color: rgba(128, 0, 128, 1)">0</span>)) + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">server.json</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
IcsMQTTServer1.Server.MultiThreaded :</span>=<span style="color: rgba(0, 0, 0, 1)"> False;
IcsMQTTServer1.IcsHosts[</span><span style="color: rgba(128, 0, 128, 1)">0</span>].BindIpAddr := conf.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ip</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
IcsMQTTServer1.IcsHosts[</span><span style="color: rgba(128, 0, 128, 1)">0</span>].BindNonPort := conf.I[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">port</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
IcsMQTTServer1.LocalBounce :</span>= conf.B[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">LocalBounce</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
user :</span>= conf.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">user</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
password :</span>= conf.S[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">password</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">];
IcsMQTTServer1.Activate(True);
end;

procedure TForm1.IcsMQTTServer1CheckUser(Sender: TObject; aUser,
aPass: UTF8String; </span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)"> Allowed: Boolean);
begin
Allowed :</span>= (aUser = user) and (aPass =<span style="color: rgba(0, 0, 0, 1)"> password);
end;

end.</span></pre>
</div>
<p>&nbsp;</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/19465258</p><br><br>
来源:https://www.cnblogs.com/hnxxcxg/p/19465258
頁: [1]
查看完整版本: TIcsMQTTServer