极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 30668|回复: 10

伪极客玩家乱入IoT之一 —— PC上的mqtt客户端程序开发

[复制链接]
发表于 2017-6-27 18:00:30 | 显示全部楼层 |阅读模式
本帖最后由 wing 于 2017-6-28 09:18 编辑

直接简单地向大家介绍一个自行开发的mqtt客户端工具,本工具可以实现最基本的订阅和发布功能。本程序无需Java或者Python环境,是完整编译可以独立运行的win32程序(当然您得确保网络通畅和防火墙放行)。

特别鸣谢OCROBOT提供免费的mqtt服务,本工具默认使用该服务mqtt.ocrobot.com

运行效果如下





完全standalone的win32可执行程序


程序的完整代码


本程序实现了最最基本的mqtt客户端功能,而且是完全开源的。
楼下有如何开发这个程序的说明,如果您不太熟悉开发工具的话在阅读时可能遇到一些困惑。
之后会扩展这个程序来实现更多的功能,我觉得这是非常有趣,希望您也喜欢

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

 楼主| 发表于 2017-6-27 18:59:54 | 显示全部楼层
本帖最后由 wing 于 2017-6-27 19:04 编辑

PS:下面这部分可能会变得比较难理解,原因可能是我也没搞得很清楚,不过幸运的是程序是能正常运作的。

物联网有无限的魅力,吸引了无数的极客。不过她的魅力远不止这样,连我这种伪极客真玩家都敢于乱入其中。
然而物联网是一个广泛的概念,如果您愿意的话大可以把完整的web服务应用在单片机上,而且事实上esp8266能很好地运行http服务。
但是为对得起自己的玩家属性,所以今天和大家谈谈主流IoT传输协议mqtt。
那么为选择mqtt?
原因是简单,实在太简单了,简单到完全不需要了解任何概念和理论都可以运用她。
只要有勇气和运气就足够了,如果您看了这么多废话还不打算关掉网页的话,那么您是幸运儿,因为本文就是为了解决运气问题的。

首先,我完全不懂mqtt服务器是怎么搭建的,不过不要紧,有人已经做好了,而且是免费的。
这里要感谢OCROBOT提供了优质的服务,下面的示例都是围绕ocrobot的服务进行的。
关于服务只需要知道两点:1主机地址mqtt.ocrobot.com;2端口1883。(很明显这个是公开的免费服务,无需用户ID和密码,完全开放)

其次,客户端我也不太明白,所以在github捡了个组件来挽救我的天真和无知。
对了,我其实是打算用delphi做一个简单的PC版mqtt客户端,版本是XE5。
如果您不打算使用这个开发工具也不要紧,本帖提供直接可以运行的程序给您试玩。

组件下载地址:https://github.com/pjde/delphi-mqtt
然后这个组件还依赖另一套网络组件:http://www.magsys.co.uk/download/wiki/icsv8w.zip
组件包里自带demo,不过这个例子太全面太复杂了,而且在没有VirtualStringTree的情况下是编译不过的。
所以我决定重写一个简单的,包括几个最基本功能:连接,断开,订阅,发布。
这几个功能分别对应程序界面上的几个按钮,这里要说明一下顺序:
第一步一定是连接;
第二步要先订阅;
第三步最后才是发布。

注意这种情况:
如果先订阅然后发布,订阅端可以收到发布的内容;
如果先发布再订阅,就收不到了。至少在most_once模式下是这样。

工程中的样子



主单元代码如下:
  1. unit ufrm_mqtt_client;

  2. interface

  3. uses
  4.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  5.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,uMQTT, uMQTTComps;

  6. type
  7.   Tfrm_mqtt_client = class(TForm)
  8.     MQTTClient1: TMQTTClient;
  9.     Label1: TLabel;
  10.     edt_host: TEdit;
  11.     Label2: TLabel;
  12.     edt_port: TEdit;
  13.     btn_connect: TButton;
  14.     btn_disconnect: TButton;
  15.     Label3: TLabel;
  16.     Label4: TLabel;
  17.     edt_topic: TEdit;
  18.     edt_message: TEdit;
  19.     btn_sub: TButton;
  20.     btn_pub: TButton;
  21.     Memo_log: TMemo;
  22.     procedure btn_connectClick(Sender: TObject);
  23.     procedure btn_disconnectClick(Sender: TObject);
  24.     procedure btn_subClick(Sender: TObject);
  25.     procedure btn_pubClick(Sender: TObject);
  26.     procedure MQTTClient1Msg(Sender: TObject; aTopic: UTF8String;
  27.       aMessage: AnsiString; aQos: TMQTTQOSType; aRetained: Boolean);
  28.     procedure FormShow(Sender: TObject);
  29.   private
  30.     aQos : TMQTTQOSType;
  31.     { Private declarations }
  32.     procedure set_log(Astr:string);
  33.   public
  34.     { Public declarations }
  35.   end;

  36. var
  37.   frm_mqtt_client: Tfrm_mqtt_client;

  38. implementation

  39. {$R *.dfm}

  40. procedure Tfrm_mqtt_client.FormShow(Sender: TObject);
  41. begin
  42.   edt_topic.Text:='/dev_dmc/m'+IntToStr(GetTickCount)+'/';
  43.   edt_message.Text:='现在的时间是'+FormatDateTime('hhnnss',now);
  44. end;

  45. procedure Tfrm_mqtt_client.set_log(Astr:string);
  46. begin
  47.   if Memo_log.Lines.Count>800 then
  48.     Memo_log.Clear;

  49.   Memo_log.Lines.Add(DateTimeToStr(now)+ ' --->> '+Astr);
  50. end;

  51. procedure Tfrm_mqtt_client.btn_connectClick(Sender: TObject);
  52. var
  53.   vport:Integer;
  54. begin
  55.   if TryStrToInt(edt_port.Text,vport) then
  56.   begin
  57.     try
  58.       MQTTClient1.Port :=vport;
  59.       MQTTClient1.Host:=edt_host.Text;
  60.       MQTTClient1.Activate (true);

  61.       set_log('连接成功');

  62.       btn_connect.Enabled:=False;
  63.       btn_disconnect.Enabled:=True;
  64.       btn_sub.Enabled:=True;
  65.       btn_pub.Enabled:=True;
  66.     except
  67.       on e:Exception do
  68.       begin
  69.         set_log('连接错误 :'+e.Message);
  70.       end;
  71.     end;
  72.   end
  73.   else
  74.   begin
  75.     set_log('端口不是有效数字');
  76.   end;
  77. end;

  78. procedure Tfrm_mqtt_client.btn_disconnectClick(Sender: TObject);
  79. begin
  80.   MQTTClient1.Activate (False);

  81.   set_log('断开连接');

  82.   btn_connect.Enabled:=  True;
  83.   btn_disconnect.Enabled:=False;
  84.   btn_sub.Enabled:=False;
  85.   btn_pub.Enabled:=False;
  86. end;

  87. procedure Tfrm_mqtt_client.btn_subClick(Sender: TObject);
  88. var
  89.   s:TStringlist;
  90. begin
  91.   s:=TStringList.Create;
  92.   try
  93.     s.AddObject(edt_topic.Text, TObject (aQos));
  94.     MQTTClient1.Subscribe (s);

  95.     set_log('订阅'+edt_topic.Text);
  96.   finally
  97.     s.Free;
  98.   end;
  99. end;

  100. procedure Tfrm_mqtt_client.btn_pubClick(Sender: TObject);
  101. begin
  102.   try
  103.     MQTTClient1.Publish(edt_topic.Text, edt_message.Text, qtAT_MOST_ONCE, false);
  104.     set_log('发布'+edt_topic.Text+' -> '+edt_message.Text);
  105.   except
  106.     on e:Exception do
  107.     begin
  108.       set_log('发布错误 :'+e.Message);
  109.     end;
  110.   end;
  111. end;

  112. procedure Tfrm_mqtt_client.MQTTClient1Msg(Sender: TObject; aTopic: UTF8String;
  113.   aMessage: AnsiString; aQos: TMQTTQOSType; aRetained: Boolean);
  114. begin
  115.   set_log('收到订阅 "' + string (aTopic) + '".长度:'+IntToStr (length (aMessage)) + ' byte(s) @ ' + QOSNames[aQos]);
  116.   set_log('信息内容:'+string (aMessage));
  117. end;

  118. end.
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2017-6-28 10:14:01 | 显示全部楼层
有点复杂,要慢慢消化一下。
回复 支持 反对

使用道具 举报

发表于 2017-6-28 15:52:53 | 显示全部楼层
看了一半天没看懂
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-30 09:48:08 | 显示全部楼层
看来大家都看不明白,强强也是这么说。
应该是我写的不清晰,其实我自己也不理解mqtt,但是作为玩家这个不是最重要的。
不懂无线电的人也能听广播,mqtt只是工具,就算不明原理,也能用她来做点什么。
下一帖来点现象级的东西:我要通过mqtt在互联网上控制一个云台
回复 支持 反对

使用道具 举报

发表于 2017-6-30 11:15:46 | 显示全部楼层
在外网也能控制?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-3 11:11:05 | 显示全部楼层
internet访问没问题的。
其实没必要看明白上面的代码,因为顶楼已经提供了直接可执行的程序,下载直接用就可以了
回复 支持 反对

使用道具 举报

发表于 2018-6-30 17:52:22 | 显示全部楼层
好东西啊~楼主能否开放一个服务端出来调试下客户端的硬件?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-1 00:56:55 | 显示全部楼层
maxims 发表于 2018-6-30 17:52
好东西啊~楼主能否开放一个服务端出来调试下客户端的硬件?

服务是有的,由ocrobot.com提供,具体情况请看最顶楼
回复 支持 反对

使用道具 举报

发表于 2018-7-20 17:16:26 | 显示全部楼层
wing 发表于 2018-7-1 00:56
服务是有的,由ocrobot.com提供,具体情况请看最顶楼

唉~以前不知道哪儿找到过一个本地服务端软件的~后来搞丢了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-7-21 11:28:34 | 显示全部楼层
maxims 发表于 2018-7-20 17:16
唉~以前不知道哪儿找到过一个本地服务端软件的~后来搞丢了。

这类软件有很多的,mqtt官方推荐的好像是 apache 的 apollo
不过目前为止我还没配置成功过

“伪极客玩家乱入IoT”系列不只两篇的,之后还有更多玩法,当然这个系列都是和mqtt相关的,希望你喜欢

喔~~~稍微剧透一下,如果自己架设服务的话考虑下带加密协议的通讯方式,这样的话之后的体验会更好
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 06:25 , Processed in 0.047330 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表