• Stars
    star
    309
  • Rank 135,280 (Top 3 %)
  • Language
    Elixir
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A MQTT Client written in Elixir

Tortoise

Build Status Hex.pm Hex version Coverage Status

A MQTT Client application that keep connections to one or more MQTT brokers, handles subscriptions, and expose a publisher for publishing messages to the broker.

Amongst other things Tortoise supports:

  • Keeping a connection to a MQTT server (version 3.1.1 for now)
  • Retry connecting with incremental back-off
  • Publishing and subscribing to topics of QoS 0, 1, and 2
  • Connections support last will message
  • Connecting via TCP and SSL
  • The fundamentals are there, but some of the API's might change in the near future
  • A PubSub system where one can listen to system events. For now connection status and ping response times can be subscribed for statistics and administrative purposes.

Most of the public facing interface should be in the Tortoise module. See the GitHub issues for work in progress "known issues in the design", "what needs to be done", and so forth; feel free to open your own issues if something is confusing or broken.

I would love to get some feedback and help building this thing.

Example

A supervised connection can be started like this:

# connect to the server and subscribe to foo/bar with QoS 0
Tortoise.Supervisor.start_child(
    client_id: "my_client_id",
    handler: {Tortoise.Handler.Logger, []},
    server: {Tortoise.Transport.Tcp, host: 'localhost', port: 1883},
    subscriptions: [{"foo/bar", 0}])

# publish a message on the broker
Tortoise.publish("my_client_id", "foo/bar", "Hello from the World of Tomorrow !", qos: 0)

To connect to a MQTT server using SSL the Tortoise.Transport.SSL transport can be used. This requires configuration of the server's CA certificate, and possibly a client certificate and key. For example, when using the certifi package as the CA trust store:

Tortoise.Supervisor.start_child(
    client_id: "smart-spoon",
    handler: {Tortoise.Handler.Logger, []},
    server: {
      Tortoise.Transport.SSL,
      host: host, port: port,
      cacertfile: :certifi.cacertfile(),
      key: key, cert: cert
    },
    subscriptions: [{"foo/bar", 0}])

Alternatively, for testing purposes, server certificate verification can be disabled by passing verify: :verify_none in the server options. In that case there is no need for CA certificates, but an attacker could intercept the connection without detection!

Look at the connection_test.exs-file for more examples.

Example Handler

defmodule Tortoise.Handler.Example do
  use Tortoise.Handler

  def init(args) do
    {:ok, args}
  end

  def connection(status, state) do
    # `status` will be either `:up` or `:down`; you can use this to
    # inform the rest of your system if the connection is currently
    # open or closed; tortoise should be busy reconnecting if you get
    # a `:down`
    {:ok, state}
  end

  #  topic filter room/+/temp
  def handle_message(["room", room, "temp"], payload, state) do
    # :ok = Temperature.record(room, payload)
    {:ok, state}
  end
  def handle_message(topic, payload, state) do
    # unhandled message! You will crash if you subscribe to something
    # and you don't have a 'catch all' matcher; crashing on unexpected
    # messages could be a strategy though.
    {:ok, state}
  end

  def subscription(status, topic_filter, state) do
    {:ok, state}
  end

  def terminate(reason, state) do
    # tortoise doesn't care about what you return from terminate/2,
    # that is in alignment with other behaviours that implement a
    # terminate-callback
    :ok
  end
end

Upgrade path

pre-0.9 to 0.9

The subscribe/3, unsubscribe/3, subscribe_sync/3, and unsubscribe_sync/3 is no longer exposed on the Tortoise module. The functionality has been moved to the Tortoise.Connection module. The functions has the same arities and functionality, so the upgrade path is a simple search and replace:

  • "Tortoise.subscribe(" -> "Tortoise.Connection.subscribe("
  • "Tortoise.subscribe_sync(" -> "Tortoise.Connection.subscribe_sync("
  • "Tortoise.unsubscribe(" -> "Tortoise.Connection.unsubscribe("
  • "Tortoise.unsubscribe_sync(" -> "Tortoise.Connection.unsubscribe_sync("

This change is done because the Tortoise.Connection module should be in charge of changes to the connection life-cycle.

Installation

Tortoise can be installed by adding tortoise to your list of dependencies in mix.exs:

def deps do
  [
    {:tortoise, "~> 0.9"}
  ]
end

Documentation should be available at https://hexdocs.pm/tortoise.

Development

To start developing, run the following commands:

mix deps.get
MIX_ENV=test mix eqc.install --mini
mix test

Building documentation

To build the documentation run the following command in a terminal emulator:

MIX_ENV=docs mix docs

This will build the documentation in place them in the doc-folder in the root of the project. These docs will also find their way to the Hexdocs website when the project is published on Hex.

License

Copyright 2018 Martin Gausby

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

More Repositories

1

gen_mqtt

DEPRECATED (use Tortoise instead): An Elixir behaviour that makes it possible to communicate with a MQTT server
Elixir
62
star
2

wifi

Various utility functions for working with the local Wifi network in Elixir. These functions are mostly useful in scripts that could benefit from knowing the current location of the computer or the Wifi surroundings.
Elixir
34
star
3

workshop

A tool for writing workshops in Elixir
Elixir
24
star
4

bit_field_set

Store and manipulate a set of bit flags, mostly used for syncing the state over the wire between peers in a peer to peer network, such as BitTorrent.
Elixir
19
star
5

bencode

A bencode encoder and decoder written in Elixir
Elixir
18
star
6

translitit-cyrillic-russian-to-latin

A cyrilic russian to latin transliteration function written in JavaScript
JavaScript
15
star
7

HTML5-YASnippet-bundle

An opinionated HTML5 YASnippet bundle. It serves my needs.
Emacs Lisp
15
star
8

torrent

work in progress
Elixir
13
star
9

pursuit

A Fast JavaScript Object Property Matching Language
JavaScript
10
star
10

scaffold

A mix task for creating new projects based on templates fetched from a Git-repo
Elixir
7
star
11

aoc2020

Don't think I will complete the full month, but if I solve any days I will post them here—probably all in Elixir
Elixir
6
star
12

mg-elixir-snippets

Personal Elixir snippets used by me, Martin Gausby. You are free to use them too, or fork them if you want to personalise them.
Emacs Lisp
6
star
13

hazel

wip
Elixir
5
star
14

level

Level for Elixir implements various helper functions and data types for working with Googles Level data store.
Elixir
5
star
15

mqtt_client

Hopefully this will become a working MQTT client
Elixir
5
star
16

ecoule

The Écoule static page engine core
JavaScript
5
star
17

matsou

A helper library for working with Riak data types in Elixir
Elixir
5
star
18

emacs.d

My Emacs setup
Emacs Lisp
5
star
19

rebelle

Start a repl session with one or more modules loaded
JavaScript
5
star
20

morse-code-presentation

An article I can point people to if they ask for slides after my live-coding session/presentation April 29
5
star
21

bon-etat

Bon état - a finite state machine.
JavaScript
5
star
22

graphql_deux

R&D Repo for wrapping graphql-erlang in Elixir
Elixir
4
star
23

example_workshop

An example workshop that show what workshop is all about
Elixir
4
star
24

prise

A utility that finds plugins for NPM based frameworks.
JavaScript
4
star
25

processes_presentation

work in progress
3
star
26

tracker

A WIP BitTorrent Tracker written in Elixir
Elixir
3
star
27

math-problem

A solution to the math problem that preschool children can solve within minutes, programmers within hours (because they have to set up unit tests) (This is a joke)
JavaScript
3
star
28

mg-org-wiki

A wiki system piggybacking on org-mode
Emacs Lisp
2
star
29

pursuit-core

A framework for building Fast JavaScript Object Property Matching Languages
JavaScript
2
star
30

vmq_plugin

(Work in progress) Convenience module for implementing VerneMQ Plugins in Elixir
Elixir
2
star
31

translitit-engine

A transliteration engine written in JavaScript
JavaScript
2
star
32

allowance

wip
Elixir
1
star
33

elixir_101_presentation

This aims to be an overview of the Elixir programming language
1
star
34

carousel

A queue that reinsert elements to the back of the queue as they are taken from it
Elixir
1
star
35

log-with-namespace-and-date-stamp

A simple log function with namespace and date-stamp
JavaScript
1
star
36

translitit-cyrillic-ukrainian-to-latin

A cyrillic ukrainian to latin transliteration module written in JavaScript
JavaScript
1
star
37

nantes

Holy giant wooden elephant, I am going to Nantes!
1
star