The server implements MQTT messaging protocol version 3.1, 3.1.1, 5.0 and allows communicate with MQTT clients to send/receive messages. The server is written in Erlang. The server was tested with following clients:
- Mosquitto command line tools subscriber and publisher
- Javascript web-socket MQTT client HiveMQ
- Erlang MQTT client
Simple Instant messenger SIM was created to test functionality of the MQTT server and prove good performance of the code. Live demo of SIM is running here.
The server consist of two OTP applications: core MQTT server and restful HTTP server for managing users DB. The both apps are combined in one release and are working closely.
Core MQTT server is an OTP application that implements MQTT protocol versions 3.1, 3.1.1 and 5.0. It depends on other Erlang applications:
lagerfor logging service,cowboyfor tcp, tls and web-socket (ws and wss) connections,msql_clientfor connection to MySQL server see,mqtt_commonthat is library keeping code that is common for MQTT client and server implementation.
Http server implements Restful API described in OpenAPI configuration file mqtt_rest_v3.yaml. There is swagger page of running instance of MQTT Rest Http server.
Storage service is using to keep information about client's sessions, subscriptions of a clients, messages during client-server communication with different QoS, users and retain messages.
The MQTT server has a three options for storage service:
- DETS implementation is using for standalone MQTT server and running in the same Erlang VM. It has maximum performance and minimum memory consuming.
- MySQL implementation is using for standalone variant or for distributed solution but all MQTT servers from cluster are connected to only separated MySQL server.
- Mnesia implementation is using for distributed MQTT servers in cluster. Mnesia DB is running on each node inside Erlang VM but connected to other nodes. This options is work fine with standalone configuration.
Server can establish connection using different network protocols:
- clear it/tcp
- tls/ssl
- web socket
- secure web socket
To start with the server you have to complete two steps below:
Download/clone source code to local host from GitHub. Type command
$ git clone https://github.com/alekras/erl.mqtt.server.git erl.mqtt.serveror download/cloan code from SourceForge
$ git clone https://git.code.sf.net/p/mqtt-server/code erl.mqtt.serverNow you have a few options how build/start server:
- compile and start from bash terminal. It is simple way and convenient for debugging and testing;
- create release and start it according to OTP rules. You can run server as single standalone mode or as cluster distributed nodes;
- build docker image and start it in standalone or cluster mode.
After you have got source code of the server then change directory to the erl.mqtt.server:
$ cd erl.mqtt.serverRun rebar3 for this project. You have to add path to rebar3 to OS PATH variable or just use the whole path:
$ /opt/local/bin/rebar3 compileRebar will fetch code of all dependencies and compile source files of main project and all dependencies.
To start server run bash script:
$ cd erl.mqtt.server
$ ./deployment_scripts/start_mqtt_server.shErlang shell will open and log statements are appearing in console.
To make release of the application for development run command:
$ /opt/local/bin/rebar3 release -n mqtt_server_devfor production:
$ /opt/local/bin/rebar3 release -n mqtt_serverExample of script to make release and start server is here
First at all you need to download and install Docker or Docker Desktop. After that you can build docker image of MQTT server:
$ cd erl.mqtt.server
$ docker build -t mqtt_server_dev --file Dockerfile .TO DO Run two containers: one mqtt server, other mnesia server. Connection to mnesia server thru RPC
TO DO Run swarm cluster with load balancer.
This kind of server run is useful for testing and debugging:
$ cd erl.mqtt.server
$ ./deployment_scripts/start_mqtt_server.shWhen you build release (see "Using relx"), now execute commands to start server in dev mode:
$ cd erl.mqtt.server
$ ./deployment_scripts/start_stop_node.sh dev consoleLet start cluster of two nodes of MQTT servers. Distributed mode of the server can run only with Mnesia storage service. When you start cluster first time Mnesia will initiate databases on different nodes and create tables. Clients can connect to any server nodes but messages will transport between clients connected to different nodes the same way as in standalone mode.
You need to do a few steps to deploy cluster:
- Open first terminal window and run command
$ cd erl.mqtt.server
$ ./start_stop_cluster_node_0.sh dev console- Open second terminal window and run command
$ cd erl.mqtt.server
$ ./start_stop_cluster_node_1.sh dev consoleNow you can connect a few MQTT clients to different ports (18883 or 28883) to test the cluster.
Build docker image (see "Build Docker image") and after that run bash script:
$ docker_run_standalone_mode.shLogging messages appear in terminal window.
You need to do a few steps to deploy cluster:
- Create docker network
$ docker network create mqtt_net - Open first terminal window and run commands
$ cd erl.mqtt.server
$ ./docker_run_cluster_node_0.sh - Open second terminal window and run commands
$ cd erl.mqtt.server
$ ./docker_run_cluster_node_1.sh Now you can connect a few MQTT clients to different ports (18883 or 28883) to test the cluster.
TO DO
TO DO
To set up ports for TCP and TLS socket connection go to config[-dev]/sys.config. This is OTP application configuration file contained startup data for lager, ranch and mqtt server backend type and connection details.
TO DO
You can test the server with any MQTT client complained with protocol version 3.1.1 or 5.0. I recommend to try Erlang MQTT client or client.
To test with Mosquitto tools you need to open two terminal windows. One for subscribing and other for publishing. Open the first terminal windows and change directory to folder where Mosquitto is installed:
$ cd /usr/local/Cellar/mosquitto/1.4.10/Now subscribe to "test/c" topic:
$ bin/mosquitto_sub -t test/c -p 18883 -i test -u guest -P guest -V mqttv5Open the second terminal windows and change directory to Mosquitto installation:
$ cd /usr/local/Cellar/mosquitto/1.4.10/Publish some message to "test/c" topic:
$ bin/mosquitto_pub -t test/c -p 18883 -i test1 -u guest -P guest -m "Test message from mosquitto tools QoS=2" -q 2 -V mqttv5In first terminal you will see incoming message:
$ Test message from mosquitto tools QoS=2The server was tested with other clients:
- Websocket MQTT client from HiveMQ [http://www.hivemq.com/demos/websocket-client/].
- MQTT Erlang client [https://github.com/alekras/mqtt_client.git].
Rest HTTP server allows to manage users table on backend DB. If you start server on local environment you can reach swagger page as http://localhost:8080/rest/v3/swagger-ui.
- [https://mosquitto.org/] - Mosquitto MQTT server.
- [https://www.rabbitmq.com/] - RabbitMQ server with MQTT plugin.
- [https://sourceforge.net/projects/mqtt-client/] - Erlang MQTT client.
- [http://www.hivemq.com/demos/websocket-client/] - MQTT websocket client.