伪极客玩家乱入IoT之一 —— PC上的mqtt客户端程序开发
本帖最后由 wing 于 2017-6-28 09:18 编辑直接简单地向大家介绍一个自行开发的mqtt客户端工具,本工具可以实现最基本的订阅和发布功能。本程序无需Java或者Python环境,是完整编译可以独立运行的win32程序(当然您得确保网络通畅和防火墙放行)。
特别鸣谢OCROBOT提供免费的mqtt服务,本工具默认使用该服务mqtt.ocrobot.com
运行效果如下
完全standalone的win32可执行程序
程序的完整代码
本程序实现了最最基本的mqtt客户端功能,而且是完全开源的。
楼下有如何开发这个程序的说明,如果您不太熟悉开发工具的话在阅读时可能遇到一些困惑。
之后会扩展这个程序来实现更多的功能,我觉得这是非常有趣,希望您也喜欢 本帖最后由 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模式下是这样。
工程中的样子
主单元代码如下:
unit ufrm_mqtt_client;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,uMQTT, uMQTTComps;
type
Tfrm_mqtt_client = class(TForm)
MQTTClient1: TMQTTClient;
Label1: TLabel;
edt_host: TEdit;
Label2: TLabel;
edt_port: TEdit;
btn_connect: TButton;
btn_disconnect: TButton;
Label3: TLabel;
Label4: TLabel;
edt_topic: TEdit;
edt_message: TEdit;
btn_sub: TButton;
btn_pub: TButton;
Memo_log: TMemo;
procedure btn_connectClick(Sender: TObject);
procedure btn_disconnectClick(Sender: TObject);
procedure btn_subClick(Sender: TObject);
procedure btn_pubClick(Sender: TObject);
procedure MQTTClient1Msg(Sender: TObject; aTopic: UTF8String;
aMessage: AnsiString; aQos: TMQTTQOSType; aRetained: Boolean);
procedure FormShow(Sender: TObject);
private
aQos : TMQTTQOSType;
{ Private declarations }
procedure set_log(Astr:string);
public
{ Public declarations }
end;
var
frm_mqtt_client: Tfrm_mqtt_client;
implementation
{$R *.dfm}
procedure Tfrm_mqtt_client.FormShow(Sender: TObject);
begin
edt_topic.Text:='/dev_dmc/m'+IntToStr(GetTickCount)+'/';
edt_message.Text:='现在的时间是'+FormatDateTime('hhnnss',now);
end;
procedure Tfrm_mqtt_client.set_log(Astr:string);
begin
if Memo_log.Lines.Count>800 then
Memo_log.Clear;
Memo_log.Lines.Add(DateTimeToStr(now)+ ' --->> '+Astr);
end;
procedure Tfrm_mqtt_client.btn_connectClick(Sender: TObject);
var
vport:Integer;
begin
if TryStrToInt(edt_port.Text,vport) then
begin
try
MQTTClient1.Port :=vport;
MQTTClient1.Host:=edt_host.Text;
MQTTClient1.Activate (true);
set_log('连接成功');
btn_connect.Enabled:=False;
btn_disconnect.Enabled:=True;
btn_sub.Enabled:=True;
btn_pub.Enabled:=True;
except
on e:Exception do
begin
set_log('连接错误 :'+e.Message);
end;
end;
end
else
begin
set_log('端口不是有效数字');
end;
end;
procedure Tfrm_mqtt_client.btn_disconnectClick(Sender: TObject);
begin
MQTTClient1.Activate (False);
set_log('断开连接');
btn_connect.Enabled:=True;
btn_disconnect.Enabled:=False;
btn_sub.Enabled:=False;
btn_pub.Enabled:=False;
end;
procedure Tfrm_mqtt_client.btn_subClick(Sender: TObject);
var
s:TStringlist;
begin
s:=TStringList.Create;
try
s.AddObject(edt_topic.Text, TObject (aQos));
MQTTClient1.Subscribe (s);
set_log('订阅'+edt_topic.Text);
finally
s.Free;
end;
end;
procedure Tfrm_mqtt_client.btn_pubClick(Sender: TObject);
begin
try
MQTTClient1.Publish(edt_topic.Text, edt_message.Text, qtAT_MOST_ONCE, false);
set_log('发布'+edt_topic.Text+' -> '+edt_message.Text);
except
on e:Exception do
begin
set_log('发布错误 :'+e.Message);
end;
end;
end;
procedure Tfrm_mqtt_client.MQTTClient1Msg(Sender: TObject; aTopic: UTF8String;
aMessage: AnsiString; aQos: TMQTTQOSType; aRetained: Boolean);
begin
set_log('收到订阅 "' + string (aTopic) + '".长度:'+IntToStr (length (aMessage)) + ' byte(s) @ ' + QOSNames);
set_log('信息内容:'+string (aMessage));
end;
end.
有点复杂,要慢慢消化一下。 看了一半天没看懂:L 看来大家都看不明白,强强也是这么说。
应该是我写的不清晰,其实我自己也不理解mqtt,但是作为玩家这个不是最重要的。
不懂无线电的人也能听广播,mqtt只是工具,就算不明原理,也能用她来做点什么。
下一帖来点现象级的东西:我要通过mqtt在互联网上控制一个云台 在外网也能控制? internet访问没问题的。
其实没必要看明白上面的代码,因为顶楼已经提供了直接可执行的程序,下载直接用就可以了 好东西啊~楼主能否开放一个服务端出来调试下客户端的硬件? maxims 发表于 2018-6-30 17:52
好东西啊~楼主能否开放一个服务端出来调试下客户端的硬件?
服务是有的,由ocrobot.com提供,具体情况请看最顶楼
wing 发表于 2018-7-1 00:56
服务是有的,由ocrobot.com提供,具体情况请看最顶楼
唉~以前不知道哪儿找到过一个本地服务端软件的~后来搞丢了。 maxims 发表于 2018-7-20 17:16
唉~以前不知道哪儿找到过一个本地服务端软件的~后来搞丢了。
这类软件有很多的,mqtt官方推荐的好像是 apache 的 apollo
不过目前为止我还没配置成功过 :(
“伪极客玩家乱入IoT”系列不只两篇的,之后还有更多玩法,当然这个系列都是和mqtt相关的,希望你喜欢
喔~~~稍微剧透一下,如果自己架设服务的话考虑下带加密协议的通讯方式,这样的话之后的体验会更好
页:
[1]