Comments (4)
Maybe just my state of mind right now, after a stressful morning, but unfortunately I am finding this request hard to follow. :-(
You are talking about outgoing messages, right? Or are you talking about something else?
I might have some ideas to help, but first I have to be able to understand the problem :-).
from tortoise.
That's quite alright, I can't explain all that well, but I tried.
My initial problem was that receiving events from MQTT is a concern that you handle with functions in the Tortoise handler (i.e., implement the right handle_message/3
callbacks). But the concern of sending an event from Elixir to the MQTT (e.g., "turn on lamp xyz") should also be a concern that you implement in that same handler module. But you cannot send a regular message to the handler process (e.g., send(HandlerId, {:foo, :bar})
) because you cannot implement callbacks for those messages in the Tortoise.Handler module. In GenServer these are the handle_info/3
callbacks.
The thing I did not notice right away is that sending a message is just a function call (Tortoise.publish/3
), so I ended up adding functions in the module myself that use Tortoise.publish/3
, and that works too, but I was wondering if there was a more idiomatic approach.
from tortoise.
The module you use for your tortoise handler is supposed to do very little, because it is running in the tortoise controller process, which means that an error in this part of the code would result in a tortoise crash, and while the code is running the controller is blocked: While most MQTT connections are not high volume I recommend doing as little as possible in the tortoise controller, and just route the messages to a process where you have all your logic for your application.
Would that work for you ?
from tortoise.
For myself[1], I ended up creating a process that receives subscribe requests from processes (e.g. scenic scenes, Phoenix live handlers, etc), and it routes the messages to the processes that have requested them. See https://github.com/brianmay/robotica-elixir/blob/master/robotica_plugins/lib/subscriptions.ex [2]. The tortoise handler is here: https://github.com/brianmay/robotica-elixir/blob/master/robotica/lib/robotica/client.ex#L84
It also keeps track on the last received message, and re-sends it on a new subscription. Ideally this probably should only happen for retained messages, but I couldn't work out how to tell them apart. For my use case all messages are retained.
It also doesn't support wildcard subscriptions. I haven't needed them.
Unfortunately, I couldn't get dynamic MQTT subscriptions to work reliably. See #130. So the mqtt subscriptions need to be hardwired into the initialization code. But regardless, this code still serves my purpose. The filtering of unwanted messages will occur in my code, not the mqtt server. If I ever got dynamic subscriptions working, I probably would want to listen to connection(:up, state)
and reconnect to all subscriptions. As currently I think tortoise might forget dynamic subscriptions on reconnect (although I guess this might change also).
Thinking about what @gausby said, possible the message()
function should be a cast not a call. But the routing shouldn't really take too long, and the actual sending is done via cast.
Notes:
[1] Code is "first working draft" status. It works, but readability probably can/should be improved now.
[2] Name subject to change because module name is misleading. I initially created RoboticaPlugins to do plugins stuff, but now it is everything except plugins stuff!
from tortoise.
Related Issues (20)
- Subscription issues with vernemq HOT 1
- Can you give me a example HOT 4
- Handle :ping_timeout more gracefully? HOT 1
- Not defining a handler prevents messages from being published HOT 7
- Beam VM becomes stucked when the number of connections is high HOT 5
- Specifying a handler module that does not implement the handler behaviour fails unintuitevly HOT 1
- errors when restarting broker HOT 2
- Questioning the handling of clean_session HOT 3
- Error on use ActiveMQ Artemis (MQTT protocol enabled) HOT 3
- AWS IoT and publish freeze on Nerves HOT 3
- No matching handle_info in Tortoise.Connection HOT 1
- subscribe can timeout for no good reason HOT 5
- Publishing a message fails when there is no connection to a broker HOT 1
- "Unexpected async result" and need to explicitly re-subscribe to topics. HOT 8
- Best way to restart connections? HOT 1
- Safest way to disconnect redundantly? HOT 1
- tortoise311 fork? HOT 5
- unknown registery: Tortoise.Regsitry HOT 1
- How to provide backpressure when too many incoming messages?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tortoise.