blob: d8de1031348d162fea9a54fb4dbf33e27c38dda6 [file] [log] [blame]
Lua MQTT client library (version 0.2 2012-06-01)
=======================
This project is part of the
[Eclipse Paho project](http://eclipse.org/paho)
Contents
--------
- [Introduction](#introduction)
- [Protocol implementation and restrictions](#restrictions)
- [Download](#download)
- [Feedback and issues](#feedback)
- [Installation](#installation)
- [Usage](#usage)
- [Example code](#example)
- [Library API](#api)
- [Known problems](#problems)
<a name="introduction" />
Introduction
------------
This project provides a client-side (only) implementation of the
[MQTT protocol](http://mqtt.org),
plus command-line utilities for publishing and subscribing to MQTT topics.
Typically, one or more MQTT servers, such as
[mosquitto](http://mosquitto.org) or
[rsmb](http://www.alphaworks.ibm.com/tech/rsmb)
will be running on host systems, with which the Lua MQTT client can interact.
MQTT stands for "Message Queue Telemetry Transport", a protocol authored by
[Dr. Andy Stanford-Clark](http://wikipedia.org/wiki/Andy_Stanford-Clark)
and Arlen Nipper.
The protocol is a message-based, publish/subscribe transport layer,
which is optimized for simple telemetry applications running on small
micro-controllers, such as an [Arduino](http://arduino.cc),
over low-bandwidth connections.
[MQTT libraries exist](http://mqtt.org/software)
for most popular programming languages, so you can utilize MQTT
on whatever server or device that you require.
The Lua MQTT client library implements the client-side subset of the
[MQTT protocol specification 3.1](https://www.ibm.com/developerworks/webservices/library/ws-mqtt).
![Lua MQTT overview](https://github.com/geekscape/mqtt_lua/raw/master/images/lua_mqtt_overview.jpg)
A good use-case for this library is running on constrained systems, such as
[OpenWRT](http://openwrt.org),
and acting as a gateway between non-MQTT clients and MQTT servers.
An advantage of using Lua is that only a text editor is required for rapid
development of simple MQTT client applications on platforms such as OpenWRT.
In constrast, working with the C programming language would comparatively
require more effort, due to requiring a cross-platform development environment.
The Lua MQTT client library also runs (unmodified) on a Sony PlayStation
Portable using the
[Lua Player HM](http://en.wikipedia.org/wiki/Lua_Player_HM)
_(which requires your PSP to be able to run unsigned executables)._
![PlayStation Portable](https://github.com/geekscape/mqtt_lua/raw/master/images/playstation_portable.jpg)
<a name="restrictions" />
Protocol implementation and restrictions
----------------------------------------
- Always assumes MQTT connection "clean session" enabled.
- Supports connection last will and testament message.
- Does not support connection username and password.
- Fixed message header byte 1, only implements the "message type".
- Only supports QOS (Quality Of Service) level 0.
- Maximum payload length is 127 bytes (easily increased).
- Publish message doesn't support "message identifier".
- Subscribe acknowledgement messages don't check granted QOS level.
- Outstanding subscribe acknowledgement messages aren't escalated.
- Works on the Sony PlayStation Portable, using
[Lua Player HM](http://en.wikipedia.org/wiki/Lua_Player_HM).
<a name="download" />
Download
--------
The Lua MQTT client library is cross-platform and should work on any
platform that supports the Lua programming language and network sockets.
- [Download Lua MQTT client library](https://github.com/geekscape/mqtt_lua/archives/master)
<a name="feedback" />
Feedback and issues
-------------------
Tracking is managed via GitHub ...
- [Enhancements requests and issue tracking](https://github.com/geekscape/mqtt_lua/issues)
<a name="installation" />
Installation
------------
You may choose to install an MQTT server either on the same or a different
system from the Lua MQTT client library, depending upon your deployment
scenario.
Prerequisites ...
- Install [Mosquitto MQTT server](http://mosquitto.org/download)
or any other MQTT server
- Install [Lua programming language](http://www.lua.org/download.html)
- Install [LuaRocks package manager](http://luarocks.org/en/Download)
- Install [LuaSocket](http://w3.impa.br/~diego/software/luasocket)
- Install [PenLight](https://github.com/stevedonovan/Penlight)
On Linux, Lua and LuaRocks can be installed via your Linux distribution
package manager.
On Mac OS X, Lua and LuaRocks can be installed viarDarwin ports.
After that, LuaSocket and PenLight can be installed via LuaRocks.
Lua MQTT client library (source code) from GitHub ...
* TODO
<a name="usage" />
Usage
-----
The Lua MQTT client library comes with three command line utilites,
which are useful for testing the library and acting as example code.
These utilities require that Lua Penlight has been installed.
#### mqtt\_test: Test publish and receive messages on different topics
This command periodically publishes a message on topic "test/1" and
subscribes to the topic "test/2". The command exits when the message
"quit" is published on topic "test/2".
cd $(LUA_MQTT_LIB) // where Lua MQTT library is installed
example/mqtt_test -d localhost // Assume MQTT server is on "localhost"
-d,--debug Verbose console logging
-i,--id (default MQTT test) MQTT client identifier
-p,--port (default 1883) MQTT server port number
<host> (default localhost) MQTT server hostname
#### mqtt\_publish: Publish a single message to a specified topic
This command publishes a single message and then exits.
example/mqtt_publish -d -t test/1 -m "Test message"
Only the _--topic_ and _--message_ parameters are required.
-d,--debug Verbose console logging
-H,--host (default localhost) MQTT server hostname
-i,--id (default MQTT client) MQTT client identifier
-m,--message (string) Message to be published
-p,--port (default 1883) MQTT server port number
-t,--topic (string) Topic on which to publish
-w,--will_message Last will and testament message
-w,--will_qos (default 0) Last will and testament QOS
-w,--will_retain (default 0) Last will and testament retention
-w,--will_topic Last will and testament topic
#### mqtt\_subscribe: Subscribe to a topic
This command subscribes to a topic and listens indefinitely for messages.
Use ^C (or similar) to stop execution.
example/mqtt_subscribe -d -t test/1
Only the _--topic_ parameter is required.
-d,--debug Verbose console logging
-H,--host (default localhost) MQTT server hostname
-i,--id (default MQTT client) MQTT client identifier
-k,--keepalive (default 60) Send MQTT PING period (seconds)
-p,--port (default 1883) MQTT server port number
-t,--topic (string) Subscription topic
-w,--will_message Last will and testament message
-w,--will_qos (default 0) Last will and testament QOS
-w,--will_retain (default 0) Last will and testament retention
-w,--will_topic Last will and testament topic
<a name="example" />
Example code
------------
The complete functioning code can be viewed here ...
[mqtt_lua/lua/example/mqtt\_test.lua](https://github.com/geekscape/mqtt_lua/blob/master/lua/example/mqtt_test.lua)
-- Define a function which is called by mqtt_client:handler(),
-- whenever messages are received on the subscribed topics
function callback(topic, message)
print("Received: " .. topic .. ": " .. message)
if (message == "quit") then running = false end
end
-- Create an MQTT client instance, connect to the MQTT server and
-- subscribe to the topic called "test/2"
MQTT = require("mqtt_library")
MQTT.Utility.set_debug(true)
mqtt_client = MQTT.client.create("localhost", nil, callback)
mqtt_client:connect("lua mqtt client"))
mqtt_client:subscribe({"test/2"})
-- Continously invoke mqtt_client:handler() to process the MQTT protocol and
-- handle any received messages. Also, publish a message on topic "test/1"
running = true
while (running) do
mqtt_client:handler()
mqtt_client:publish("test/1", "test message")
socket.sleep(1.0) -- seconds
end
-- Clean-up by unsubscribing from the topic and closing the MQTT connection
mqtt_client:unsubscribe({"test/2"})
mqtt_client:destroy()
There are also a number of Lua MQTT client examples in the _example/_ directory.
They can be run from the _lua/_ parent directory, as follow ...
cd mqtt_client/lua
example/example_00.lua
<a name="api" />
MQTT client Library API
-----------------------
Once the MQTT client library has been included (via _require_), one or more
MQTT server connections can be created. Using a server connection, the client
may then publish messages directly on a specified topic. Or, subscribe to one
or more topics, where received messages are passed to a callback function
(defined when creating an MQTT client instance). Finally, the client can
unsubscribe from one or more topics and disconnect from the MQTT server.
Use the Lua _require_ statement to load the MQTT client library ...
MQTT = require("mqtt_library")
#### MQTT.Utility.set_debug(): Library debug console logging
The following statement enables debug console logging for diagnosis.
MQTT.Utility.set_debug(true)
#### MQTT.client.create(): Create an MQTT client instance
Create an MQTT client that will be connected to the specified host.
mqtt_client = MQTT.client.create(hostname, port, callback)
The _hostname_ must be provided, but both the _port_ and _callback function_
parameters are optional. This function returns an MQTT client instance
that must be used for all subsequent MQTT operations for that server connection.
hostname string: Host name or address of the MQTT broker
port integer: Port number of the MQTT broker (default: 1883)
callback function: Invoked when subscribed topic messages received
The _callback function_ is defined as follows ...
function callback(topic, payload)
-- application specific code
end
topic -- string: Topic for the received message
payload -- string: Message data
#### MQTT.client:destroy(): Destroy an MQTT client instance
When finished with a server connection, this statement cleans-up all resources
allocated by the client.
mqtt_client:destroy()
#### MQTT.client:connect(): Make a connection to an MQTT server
Before messages can be transmitted, the MQTT client must connect to the server.
mqtt_client:connect(identifier)
Each individual client connection must use a unique identifier.
Only the _identifier_ parameter is required, the remaining parameters
are optional.
mqtt_client:connect(identifier, will_topic, will_qos, will_retain, will_message)
MQTT also provides a "last will and testament" for clients, which is a message
automatically sent by the server on behalf of the client, should the connection
fail.
identifier -- string: MQTT client identifier (maximum 23 characters)
will_topic -- string: Last will and testament topic
will_qos -- byte: Last will and testament Quality Of Service
will_retain -- byte: Last will and testament retention status
will_message -- string: Last will and testament message
#### MQTT.client:disconnect(): Transmit MQTT Disconnect message
Transmit an MQTT disconnect message to the server.
mqtt_client:disconnect()
#### MQTT.client:publish(): Transmit MQTT publish message
Transmit a message on a specified topic.
mqtt_client:publish(topic, payload)
topic -- string: Topic for the published message
payload -- string: Message data
#### MQTT.client:subscribe(): Transmit MQTT Subscribe message
Subscribe to one or more topics. Whenever a message is published to one of
those topics, the callback function (defined above) will be invoked.
mqtt_client:subscribe(topics)
topics -- table of strings, e.g. { "topic1", "topic2" }
#### MQTT.client:handler(): Handle received messages, maintain keep-alive messages
The _handler()_ function must be called periodically to service incoming
messages and to ensure that keep-alive messages (PING) are being sent
when required.
The default _KEEP\_ALIVE\_TIME_ is 60 seconds, therefore _handler()_ must be
invoked more often than once per minute.
Should any messages be received on the subscribed topics, then _handler()_
will invoke the callback function (defined above).
mqtt_client:handler()
#### MQTT.client:unsubscribe(): Transmit MQTT Unsubscribe message
Unsubscribe from one or more topics, so that messages published to those
topics are no longer received.
topics -- table of strings, e.g. { "topic1", "topic2" }
<a name="problems" />
Known problems
--------------
- Occasional "MQTT.client:handler(): Message length mismatch" errors,
particularly when subscribed topics are transmitting many messages.
- Not really a problem, but if you find that the MQTT socket connection is
being closed for no apparent reason, particularly for subscribers ...
then check that all MQTT clients are using a unique client identifier.