Handling multiple protocols in Channels 2

98 views
Skip to first unread message

Andrea Conti

unread,
May 2, 2019, 7:40:20 AM5/2/19
to Django users
Hello,

I am trying to use Channels 2 to implement an http/websocket application which also handles asynchronous requests from  a second source (right now it's messages from an MQTT subscription, but I think the problem is largely independent from the specific protocol). This doesn't seem to be a common use case, and I could not find any indication on how to do that, either in the official Channels documentation or elsewhere

Given that I must handle the contents of the MQTT messages in the same process as the websocket requests, the ideal approach would be to run both the http/websocket and the MQTT protocol handlers in the same process, but I am quite certain I can't do that.

My next thought would then be to have a second process for handling the incoming messages and sending them to the main application as events over a channel layer. 

For the MQTT side, leaving the specific protocol aside, I have seen examples using asgiref.server.StatelessServer (e.g. https://github.com/andrewgodwin/asgigram), but that ends up creating a scope from the event and passing it to an ASGI application instance -- i.e. it handles the events in-process, which is not what I want.

Then there's https://github.com/xavierlesa/channels-asgi-mqtt. The code looks a bit messy, and I think it's been written for Channels 1, but the principle seems clear: retrieve the default channel layer and for every incoming message, send an event of a specific type to a channel with a specific name.

But then, how do I receive and handle events from the channel in the websocket process? 
https://channels.readthedocs.io/en/latest/topics/channel_layers.html says that "Messages across channel layers also go to consumers/ASGI application instances, just like events from the client", and https://channels.readthedocs.io/en/latest/topics/worker.html seems to imply that such events are simply available to the main ASGI application -- but that relies on a having a dummy protocol handler (channels.worker.Worker) subscribe to a set of channels and wrap each event in a scope which is then passed to the ASGI application. So, once again that would seem to require a second protocol handler besides the http/websocket one. 

Am I missing something?

Any Ideas, corrections and pointers to relevant documentation and examples are welcome.

Thanks in advance,
Andrea

Fly Style

unread,
May 2, 2019, 8:33:01 AM5/2/19
to Django users

have a try  of https://github.com/ruralscenery/channels_mqtt

Andrea Conti於 2019年5月2日星期四 UTC+8下午7時40分20秒寫道:

Andrea Conti

unread,
May 2, 2019, 11:17:02 AM5/2/19
to Django users

First of all, thanks for responding.

While the example does route the incoming MQTT messages to a consumer, the consumer is still in the same process as the MQTT client, i.e. the one started with "runmqttworker" management command.

What I am trying to do is tohandle those events within another process.

Andrea

Fly Style

unread,
May 6, 2019, 12:13:07 AM5/6/19
to Django users

you could send  message to channel "mqtt" that defined in routing.py via django channels usage

Andrea Conti於 2019年5月2日星期四 UTC+8下午11時17分02秒寫道:

Fly Style

unread,
May 6, 2019, 12:26:52 AM5/6/19
to Django users
for example:

from asgiref.sync import async_to_sync as a2s
from channels.layers import get_channel_layer
from channels_mqtt import settings


event = {"type": settings.MQTT_PUBLISH, "text": {"topic": topic, "payload": payload, "qos": qos, "retain": retain}}
a2s
(channel_layer.send)(channel, event)

Andrea Conti

unread,
May 6, 2019, 12:49:23 PM5/6/19
to Django users

Ok, but that doesnt'solve the problem with handling the events in the right process.

Anyway, I think I figured it out. It seems there is nothing magical to a 'protocol handler' after all, so I can just create a thread with its event loop and run the MQTT listener in there. No other processes required, and I don't even need to use a channel layer as long as I can live without the group facilities.

Runs fine in development mode, let's hope it does not blow up with an external ASGI server.

andrea
Reply all
Reply to author
Forward
0 new messages