MQTT
MQ Telemetry Transport (MQTT) is a client-server publish/subscribe messaging protocol for resource-constrained devices in low bandwidth environments. The protocol is popular in Internet of Things applications, especially for machine-to-machine communication. An MQTT client connects to an MQTT server, also known as broker, over a network, and is then able to receive messages from and publish messages to topics.
MQTT client libraries have been implemented in many programming languages, for example:
- Eclipse Paho (C, C++, Java, JavaScript, Python, Go, …)
- MQTT-C (C)
- luamqtt (Lua)
- PubSubClient (Arduino)
Several MQTT server implementations exist that are licenced as open source:
- Eclipse Mosquitto (Linux, Unix, macOS, Microsoft Windows)
- Apache ActiveMQ (Java)
- HMBQTT (Python)
- VerneMQ (Linux)
The fortran-paho library provides a collection of ISO C binding interfaces to Eclipse Paho for publish/subscribe message passing in Fortran.
Installation
At first, we have to download and compile the Eclipse Paho C library. CMake is required to create the necessary build scripts:
$ git clone https://github.com/eclipse/paho.mqtt.c
$ cd paho.mqtt.c/
$ mkdir build && cd build/
$ cmake ..
$ make
$ make install
We can then compile the fortran-paho interface bindings:
$ git clone https://github.com/interkosmos/fortran-paho
$ cd fortran-paho/
$ make
This outputs the static library libfortran-paho.a
. Link your
Fortran applications with libfortran-paho.a -lpaho-mqtt3c
to access
Eclipse Paho.
Additionally, we have to install an MQTT server. Eclipse Mosquitto should be available on most Unix-like operating systems. On FreeBSD, simply run:
# pkg install net/mosquitto
Make sure Mosquitto is actually running on localhost
before
connecting any clients:
# service mosquitto onestart
Starting mosquitto.
Example
The following Fortran 2008 example publishes a plain-text message to topic
fortran
on the local MQTT broker instance. We can run
mosquitto_sub
, which is part of Mosquitto, to subscribe the topic and
print incoming messages to console:
$ mosquitto_sub -h 127.0.0.1 -t fortran
The subscribing client has to be started before the Fortran program publishes any messages, as the retained flag is not set.
! publish.f90
program main
use, intrinsic :: iso_c_binding
use, intrinsic :: iso_fortran_env, only: int64
use :: paho
implicit none
character(len=*), parameter :: ADDRESS = 'tcp://localhost:1883' ! MQTT server address.
character(len=*), parameter :: CLIENT_ID = 'FortranPubClient' ! MQTT client name.
character(len=*), parameter :: TOPIC = 'fortran' ! MQTT topic.
character(len=*), parameter :: TEXT = 'Hello, from Fortran!' ! Message text.
integer, parameter :: QOS = 1 ! Quality of Service (QoS).
integer, parameter :: TIMEOUT = 10000 ! Timeout in milliseconds.
type(c_ptr) :: client
type(mqtt_client_connect_options) :: conn_opts = MQTT_CLIENT_CONNECT_OPTIONS_INITIALIZER
type(mqtt_client_message) :: pub_msg = MQTT_CLIENT_MESSAGE_INITIALIZER
integer :: token
integer :: rc
! The payload string with null-termination.
character(len=len(TEXT) + 1), target :: payload = TEXT // c_null_char
! Create MQTT client.
rc = mqtt_client_create(client, &
ADDRESS // c_null_char, &
CLIENT_ID // c_null_char, &
MQTTCLIENT_PERSISTENCE_NONE, &
c_null_ptr)
conn_opts%keep_alive_interval = 20
conn_opts%clean_session = 1
! Connect to MQTT message broker.
rc = mqtt_client_connect(client, conn_opts)
if (rc /= MQTTCLIENT_SUCCESS) then
print '(a, i0)', 'Failed to connect: ', rc
stop
end if
! Initialise message.
pub_msg%payload = c_loc(payload) ! Payload contents.
pub_msg%payload_len = len(payload) ! Payload size.
pub_msg%qos = QOS ! Quality of Service (QoS).
pub_msg%retained = 0 ! Retained flag.
! Publish message.
rc = mqtt_client_publish_message(client, TOPIC // c_null_char, pub_msg, token)
print '(a, i0, 7a)', 'Waiting for up to ', TIMEOUT / 1000, ' second(s) for publication of "', &
trim(payload), '" on topic "', TOPIC, '" from client with id "', &
CLIENT_ID, '"'
rc = mqtt_client_wait_for_completion(client, token, int(TIMEOUT, kind=int64))
print '(a, i0, a)', 'Message with delivery token ', token, ' delivered'
! Disconnect.
rc = mqtt_client_disconnect(client, TIMEOUT)
call mqtt_client_destroy(client)
end program main
Compile the program with:
$ gfortran12 -I/usr/local/include/ -L/usr/local/lib/ \
-o publish publish.f90 libfortran-paho.a -lpaho-mqtt3c
Once started, the example program will connect to the MQTT server and publish the message to the set topic:
$ ./publish
Waiting for up to 10 second(s) for publication of "Hello, from Fortran!" on topic "fortran"
from client with id "FortranPubClient"
Message with delivery token 1 delivered
Any MQTT client already subscribing the topic will receive the message:
$ mosquitto_sub -h 127.0.0.1 -t fortran
Hello, from Fortran!
Fortran Libraries
- fortran-paho: Fortran 2008 interface bindings to the Eclipse Paho MQTT client library
References
- Eclipse Paho: MQTT client library
- Eclipse Mosquitto: MQTT server/broker
< ZeroMQ | [Index] | UNIX System V Message Queues > |