brianmay

brianmay

Hello,

Is there a good mqtt client library for Elixir? Getting a bit disillusioned, none of the options seem very good.

  • GitHub - gausby/tortoise: A MQTT Client written in Elixir · GitHub - initially seemed very good. Particularly with the rewrite mqtt-5 support - which I suspect is in the mqtt-5 branch. But has numerous bugs, particularly when mqtt server goes down (pub requests can hang - hanging my application) or if trying to dynamically subscribe to topics at run-time. These errors aren’t always easy to reproduce on demand, and at one stage I was told that there were fundamental design issues. Was looking forward to the rewrite, but development has stalled, and status unclear. I don’t blame the author in anyway (I have a lot of projects in this state myself). Would consider contributing to mqtt-5 branch development if this is the best option.

  • GitHub - jacky-xbb/exmqtt: Elixir MQTT v5.0 Client · GitHub - no development for 15 months. But does support MQTT 5 - according to description at least.

  • A number of other options that look hopeful, but looks like development has also stalled.

  • Maybe I should be looking at erlang solutions? e.g. GitHub - emqx/emqtt: Erlang MQTT 5.0 Client · GitHub looks like it is actively maintained.

So wondering what the best option forward is. Examples:

  • Take over the development of the mqtt-5 branch on tortoise.
  • Take over another project.
  • Learn about MQTT-5 and start my own project from scratch?
  • Write Elixir wrapper for Erlang solution.

I tend to favor the last option right now. Unless of course somebody has already written such a wrapper.

But would appreciate any opinions,

Showing Posts 1 to 10

brianmay

brianmay OP

GitHub - ryanwinchester/exmqtt: Elixir wrapper for emqx/emqtt · GitHub - interesting. No development for 2 years. But might be really good starting point.

brianmay

brianmay OP

Hmmm. Something weird with emqtt. exmqtt a lot of nice logic to handle gentle back-offs with retries if there is a connection fault. But none of this actually gets used.

Still not 100% clear what is going on. It appears that emqtt.connect(conn_pid) |> IO.inspect() returns and will print the error result. But if I have a call to IO.puts("xxxx") immediately following, it will never get called. Then the genserver process gets recreated 4 times.

Initially I thought maybe an exception is being generated and silently discarded. But I can’t see any evidence of this actually happening.

I think that the genserver process is silently getting killed by another process immediately after an error. And the supervisor recreates it 4 times, before the supervisor dies. Which is standard supervisor behavior. But the supervisor doesn’t print any messages about the process having died. But still is my most likely theory. Maybe the supervisor sees it as a normal exit, not an error exit, so doesn’t print anything.

If correct, this is a bit awkward, I want to process the errors myself, and not have my genserver killed.

If anybody else is interested in testing, I can publish my test code and it should be easy to reproduce.

brianmay

brianmay OP

My bad. Need to call:

Process.flag(:trap_exit, true)

Duh!

Sebb

Sebb

I would go with emqtt.
There seems to be zero documentation on the web how to use it with Elixir.
We should change that.

Here is a starting point. (connects to test.mosquitto.org with no auth and subscribes to # so you get lots of messages)

deps (latest - 1.4.0 - seems to be out of sync with the docs in readme)

{:emqtt, github: "emqx/emqtt", tag: "v1.2.0"},

some code

defmodule MqttHowto do
  def hello do
    opts = [
      clientid: "my_client_id",
      host: 'test.mosquitto.org',
      port: 1883
    ]

    {:ok, pid} = :emqtt.start_link(opts)
    {:ok, _} = :emqtt.connect(pid)
    {:ok, _, _} = :emqtt.subscribe(pid, %{}, [{"#", []}])

    recv()
  end

  def recv() do
    receive do
      message -> IO.inspect(message)
    end

    recv()
  end
end

Sebb

Sebb

yes please do that

brianmay

brianmay OP

See GitHub - brianmay/mqtt_potion: Elixir wrapper for emqtt · GitHub for what I have done so far.

Basically a fork for the existing exmqtt, with some improvements. Including writing a simple test client. Which is a layer on top of emqtt. Which seems to be the recommended approach based on feedback so far.

Going to have to rename the project so I have the option to upload to hex.pm - this name is already taken by what looks like a different project. Thinking maybe mqtt_potion or something.

Progress: receiving messages works, reconnect appears to work if server goes down. But not tested any of the publish or subscribe methods.

Also the disconnect method is perhaps a bit misleading, it is more like a ‘reconnect’ I think (not tested).

Probably should test what happens if the client makes requests and the connection is offline. Ideally this shouldn’t kill the genserver and error returned to client (if sync request).

Pull requests welcome :slight_smile:

brianmay

brianmay OP

Looks like my first attempt to build emqtt in github actions was a little bit less then successful.

https://github.com/brianmay/exmqtt/runs/3064947467

[ 83%] Building C object CMakeFiles/quicer_static.dir/c_src/quicer_listener.c.o
cc1: error: too many filenames given.  Type cc1 --help for usage
cc1: error: too many filenames given.  Type cc1 --help for usage
cc1: fatal error: CMakeFiles/quicer_static.dir/c_src/quicer_queue.c.d: No such file or directory
compilation terminated.

Huh? Weird.

Sebb

Sebb

Do you think its worth the effort to build a wrapper?
Obviously there is very low demand for an Elixir MQTT-client.
You are forking a repo that received one like in two years…

I’d use emqtt directly. Some documentation how to do that would be really helpful.

brianmay

brianmay OP

I think there are Two questions here, which I will answer:

  1. Why create a separate project?

I will face the same challenges regardless if I add the code directly to my project or not. Plus this way I am more likely to be able to get help, then if it it integrated into my project with numerous external dependencies. And I get to reuse the same code in my other projects.

There is at least one other open source software project I use that uses tortoise. Would be good to move these projects to something better supported. In fact based on the tortoise bug reports I see, I think there are a number of people who incorrectly feel that is the only option available. So demand might be higher then you think.

  1. Why base on project that is 2 years old?

The code structure + my changes is very similar to what I would be used anyway, and similar to what my existing code already expects (being based on tortoise).

While your code certainly looks simple, I believe it wouldn’t try to gracefully reconnect if there is a connection error. In fact a connection error will kill the process that called hello - as I discovered earlier - because the emqtt process is linked, when the connection dies, it dies, which will in turn kill the calling process. As these are long running processes, that is important for me, and where most of the complexity lies.

Yes better documentation would be very useful. e.g. Took me ages to work out how to get mqtt over TLS working with peer verification enabled.

brianmay

brianmay OP

I wonder if emqtt supports IPv6? My suspicion is maybe not. As I believe my hostname I provided was getting translated to an IPv4 address, which is why the TLS peer verification wasn’t working.

Later: Looks like this issue was closed without actually fixing the problem :frowning:
https://github.com/emqx/emqx/issues/768

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews