IOT程序员我爱编程

开始使用MQTT(译)

2017-03-15  本文已影响376人  ZZES_ZCDC

原文标题:getting started mqtt
作者:Arvind Ravulavaru
翻译:治电小白菜
原文地址:http://thejackalofjavascript.com/getting-started-mqtt/
注意:发现文章中用的mqtt模块版本过低,导致有些语法失效了,比如,创建客户端的函数createClient在最新版的mqtt已经失效.改用为mqtt.connect。这些我已经在代码中做了更改,并且已经运行成功。

在这篇文章中,我们将瞧一瞧一个通信协议,名字叫做Message Queue Telemetry Transport (MQTT).MQTT是一个轻量的,安全的,省电的以及一个机器对机器(M2M)/“物联网”(Internet of Things)的连接协议。

来自Cirrus Link Solutions的Andy Stanford-Clark 和 Arlen Nipper 在 1999 年编写了这个协议的第一个版本。

什么是MQTT

MQTT(全称Message Queue Telemetry Transport)是一个基于顶层TCP/IP协议的有发布/订阅功能的轻量通信协议。它被设计来连接需要“小型代码封装”(“small code footprint”)或者网络带宽被限制的远程区域。发布/订阅信息模式要求一个信息代理。信息代理负责分发信息给订阅了一个信息话题的客户端。
<br >
说明文档没有明确“小型代码封装”(“small code footprint”)和“限制网络带宽”的含义。因此,协议的可用性取决于上下文的使用。在2013年,IBM将MQTT V3.1提交给 OASIS规范,确定只对规范进行可接受的小幅动的改动。MQTT-SN是一个主协议的变种,针对在non-TCP/IP网络下的嵌入式设备,比如ZigBee。


历史上,‘MQTT’的‘MQ’来自于IBM的MQ消息队列产品线。然而,队列本身不需要在所有情况下支持作为标准特性。

现实世界的应用

Facebook Messenger:Facebook已经在Facebook Messenger很多方面中使用了MQTT。然而还不确定使用了多少MQTT以及在哪个方面使用了MQTT;另外,要注意这是一个手机应用,不是一个传感器应用。

理解OSI模型

为了更加理解MQTT的使用范围,你需要对OSI模型有一定的理解。如果你已经知道了这个,你可以跳过下面的视频。


翻墙观看:https://www.youtube.com/embed/sVDwG2RdJho?rel=0


MQTT和HTTP处于同一层,是第7层。

为什么选择MQTT?

  1. 它是一个订阅/发布协议
  2. 它有不同质量的服务等级(QOS)
  3. 它有消息至少处理一次(at-least-once)和只执行一次(exactly-once)语义
  4. 它有一个很低的日常开支(最少2bytes)
  5. 它支持离线信息
  6. 它像一个键/值存储一样来保留信息

Matteo Collina,Mosca的作者,给了一个很棒的演说,来演讲什么是MQTT以及它如何通过Nodejs工作。


翻墙观看:https://www.youtube.com/embed/WE7GVIFRV7Q?rel=0


你可以在这个网址查看他关于MQTT和Node.js演讲的演示。http://mcollina.github.io/mqtt_and_nodejs/

MQTT将会被应用到哪里?

想象下面的环境

mqtt_arch.png

在单个机器/设备的状态/传感器数据需要传递给其他机器/设备,以及一个实时仪表、一个平板或者一个可穿戴设备。连接和维持数据传输,很多设备或许是棘手的。这种情况下可以使用MQTT。

亲自动手

现在我们已经对于MQTT有了一定的理解,我们将尝试一个简单的例子。我们将实现一个服务/代理 通过Mosca来接收数据并发放到所有他的客户端。然后我们将使用MQTT.js实现一个MQTT客户端从代理处发布和订阅一个话题。


创建一个名为mqttApp的文件夹,我们将在它里面创建两个文件夹,分别叫server,client.


server文件夹内打开命令行,创建一个新的Node.js项目,通过运行

 npm init

然后,我们将安装Mosca依赖,以及保存它到package.json中。运行

npm install mosca --save

server文件夹内创建名为server.js的文件。将以下代码写入其中

var mosca = require('mosca')
var settings = {
port: 1883
};
//启动mosca
var server = new mosca.Server(settings);
server.on('ready', setup);
// 启动后发出
function setup() {
console.log('Mosca server is up and running')
}
// 客户端连接后发出
server.on('clientConnected', function(client) {
console.log('client connected', client.id);
});
//接收到信息时发出
server.on('published', function(packet, client) {
console.log('Published : ', packet.payload);
});
// 客户端订阅了一个主题时发出
server.on('subscribed', function(topic, client) {
console.log('subscribed : ', topic);
});
// 客户端取消订阅一个主题时发出
server.on('unsubscribed', function(topic, client) {
console.log('unsubscribed : ', topic);
});
// 客户端断开连接时发出
server.on('clientDisconnecting', function(client) {
console.log('clientDisconnecting : ', client.id);
});

一个简单的MQTT代理服务器。这些事情要注意

简单的 pub/sub API


如果你想启用离线模式,我们需要存储数据到一个键值对的数据库。开箱即用的Mosca支持大多数著名的键值对数据库。下面是一个快速的例子,教你如何使用它,使用MongoDB。


更新server.js

var mosca = require('mosca')
var pubsubsettings = {
type: 'mongo',
url: 'mongodb://localhost:27017/mqtt',
pubsubCollection: 'myCollections',
mongo: {}
};
var settings = {
port: 1883,
backend: pubsubsettings
};
//here we start mosca
var server = new mosca.Server(settings);
server.on('ready', setup);
// fired when the mqtt server is ready
function setup() {
console.log('Mosca server is up and running')
}
// fired whena  client is connected
server.on('clientConnected', function(client) {
console.log('client connected', client.id);
});
// fired when a message is received
server.on('published', function(packet, client) {
console.log('Published : ', packet.payload);
});
// fired when a client subscribes to a topic
server.on('subscribed', function(topic, client) {
console.log('subscribed : ', topic);
});
// fired when a client subscribes to a topic
server.on('unsubscribed', function(topic, client) {
console.log('unsubscribed : ', topic);
});
// fired when a client is disconnecting
server.on('clientDisconnecting', function(client) {
console.log('clientDisconnecting : ', client.id);
});

只有在第3行有改变。我们在那里增加了MongoDB设置。(你可以使用一个服务像Mongo Lab,将数据存储到云里。)然后我们在第12行处引入这些设置.


在我们启动服务器之前,我们需要启动MongoDB实例。如果你是MongoDB新手,可以看看这个http://thejackalofjavascript.com/mapreduce-in-mongodb/#mongodb


一旦MongoDB启动,我们将通过下面的命令开启服务器

node server.js

如果MongoDB开启并运行了,你应该就能看到成功的信息。否则你将看到一堆错误。


这是一个简单的实现离线功能的代理服务器。在我们更进一步之前,我们将更新我们的服务器变成一个实时的代理服务器。使用下列代码更新server.js

var mosca = require('mosca')
var settings = {
port: 1883,
persistence: mosca.persistence.Memory
};
var server = new mosca.Server(settings, function() {
console.log('Mosca server is up and running')
});
server.published = function(packet, client, cb) {
if (packet.topic.indexOf('echo') === 0) {
return cb();
}
var newPacket = {
topic: 'echo/' + packet.topic,
payload: packet.payload,
retain: packet.retain,
qos: packet.qos
};
console.log('newPacket', newPacket);
server.publish(newPacket, cb);
}

这里我们钩取了一个服务器发布事件的回调,然后创建了一个新的数据包包含每个接受到的信息,然后将新的数据包发送给客户端。




现在,我们将构建一个可以发布/订阅主题的MQTT客户端。在client文件夹内打开一个命令行。


我们的客户端将是另一个Node.js应用。在这个例子里,都是运行在同一个机器。但是在正式情况下,客户端程序将被部署到实际的设备上,比如Pi或者Arduino。以及服务器将会被部署到云中。


现在,运行

npm init

MQTT.js依赖将会被引入,运行

npm install mqtt --save

client文件夹内创建一个名为client1.js的文件。我们将在本地机器中模拟两个客户端,来看事件如何运作的。在client1.js中写入以下代码

var mqtt = require('mqtt')
// client = mqtt.createClient(1883,'localhost');
var client  = mqtt.connect('mqtt://127.0.0.1:1883')
client.on('connect', function () {
  client.subscribe('presence')
  client.publish('presence', 'Client 1 is alive.. Test Ping! ' + Date())
  console.log('Client publishing..')
  client.end()
})

以下事情需要注意



我们将创建另一个客户端,来监听“presence”话题的改变。在client文件中创建一个名为client2.js的文件。在其中写入以下的代码

var mqtt = require('mqtt')
// client = mqtt.createClient(1883,'localhost');
client  = mqtt.connect('mqtt://127.0.0.1:1883')
client.subscribe('presence');
client.on('message',function(topic,message){
    console.log(message.toString());
});
console.log('client started ...');

client1.js一样,除了这个客户端只是监听主题的改变


为了测试这个,第一步我们将开启服务器。运行

node server.js

然后你应该能够看到服务器开启日志。然后运行 client2

node client2.js

你应该能看到客户端开启日志。最后运行 client1

node client1.js

服务器命令行应该会有反映

1.png

最后的数据包是我们“presence”主题。以及client2 命令行应该看到这个

2.png

简单明了的基于MQTT协议的会话!


你可以在这里看到这个例子的完整代码。https://github.com/klren0312/moscaTest

可以看Matteo Collina 的视频,关于他现场编码一个机器人以及通过网页控制它 – LXJS 2014


翻墙观看:https://www.youtube.com/embed/BxJ-27Nnakc?rel=0

希望这篇文章能给你一些关于如何在Node.js中使用MQTT的思路。


@arvindr21

上一篇下一篇

猜你喜欢

热点阅读