Как использовать клиент paho mqtt в django?

Я пишу приложение django, которое должно действовать как издатель MQTT и как подписчик.

Где мне запустить клиент paho и запустить функцию loop_forever().

Должен ли он быть в wsgi.py?


person Raja Sudhan    schedule 07.12.2016    source источник
comment
loop_forever() будет блокироваться навсегда, поэтому, вероятно, его следует запустить в своем собственном потоке.   -  person hardillb    schedule 07.12.2016


Ответы (1)


Обновление:

Если вам нужно, чтобы Django работал в нескольких потоках, то для публикации сообщений из вашего приложения Django вы можете использовать вспомогательные функции из модуля публикации Paho — https://eclipse.org/paho/clients/python/docs/#id17. В этом случае вам не нужно создавать экземпляр клиента mqtt и запускать цикл. А чтобы подписаться на какую-то тему, запустите клиент mqtt как отдельный скрипт и импортируйте туда необходимые модули вашего приложения Django (и не забудьте настроить среду Django в скрипте).


Ответ ниже подходит только в том случае, если вы запускаете Django в одном потоке, что необычно в рабочей среде.

Создайте mqtt.py в папке приложения и поместите туда весь соответствующий код. Например:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, rc):
    client.subscribe("$SYS/#")

def on_message(client, userdata, msg):
    # Do something
    pass

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("iot.eclipse.org", 1883, 60)

Не звоните сюда loop_forever()!

Затем в своем приложении __init__.py вызовите loop_start():

from . import mqtt

mqtt.client.loop_start()

Использование loop_start() вместо loop_forever() позволит вам не блокировать фоновый поток.

person Max Polezhaev    schedule 07.12.2016
comment
Спасибо Макс, работает отлично! У меня есть еще одно сомнение: что произойдет, если я масштабирую веб-процесс, создающий несколько клиентов mqtt? Если да, то как мне это остановить? - person Raja Sudhan; 07.12.2016
comment
@RajaSudhan, что вы подразумеваете под масштабированием веб-процесса? - person Max Polezhaev; 07.12.2016
comment
При запуске приложения django в производстве я развертываю его на нескольких серверах с балансировщиком нагрузки, поэтому я не хочу прослушивать сообщения на всех хостах. - person Raja Sudhan; 15.12.2016
comment
@RajaSudhan хорошо, теперь я понимаю твою озабоченность. Вы правы, если вы запускаете Django в несколько потоков (как это обычно бывает в продакшене), то не стоит запускать подписчика в каждом потоке, потому что on_message в этом случае будет срабатывать в каждом потоке для одного сообщения, а вы хотите, чтобы он огонь только один раз. Рассмотрите возможность запуска клиента mqtt как отдельного скрипта и импортируйте туда необходимые модули вашего приложения Django (не забудьте настроить среду Django в этом скрипте). - person Max Polezhaev; 16.12.2016
comment
@RajaSudhan мой предыдущий комментарий был о подписке. А для публикации из Django вы можете использовать вспомогательные функции из модуля публикации Paho, смотрите обновления в моем ответе. - person Max Polezhaev; 16.12.2016
comment
это нормально работает с ./manage.py runserver, но не с: /usr/local/bin/uwsgi --socket :7011 --module myproject.wsgi Почему? - person user2239318; 08.03.2017
comment
@ user2239318, можете ли вы предоставить более подробную информацию? Вы видите какие-то исключения? Можете ли вы поделиться кодом вашего проекта? Также имейте в виду, что код в моем ответе подходит только в том случае, если вы запускаете Django в одном потоке, см. обновленную часть ответа. - person Max Polezhaev; 09.03.2017
comment
Когда я это делаю, я фактически 3 раза запускаю скрипт в продакшене, есть ли у кого-нибудь ответы_ - person Javier Campos; 19.09.2017
comment
@JavierCampos, какой скрипт вы запускаете 3 раза? Не могли бы вы предоставить более подробную информацию? - person Max Polezhaev; 20.09.2017
comment
@MaxPolezhaev Я использую пушку, в настройках у меня 3 работы, поэтому скрипт запускается 3 раза... как этого избежать? (когда я ставлю 1 работу, все работает нормально) - person Javier Campos; 27.09.2017
comment
@JavierCampos, вам нужен автономный скрипт, который не импортируется в ваше приложение Django. Вам нужно будет выполнить этот скрипт с помощью systemd или того, что вы используете (не из Django, который запускается 3 раза рабочими). - person Max Polezhaev; 06.10.2017
comment
@MaxPolezhaev и я смогу писать в Django db с помощью функций django? - person Javier Campos; 08.10.2017
comment
@JavierCampos Да, вы сможете использовать Django ORM и все свои модели в отдельном скрипте. Но не забудьте настроить среду Django в скрипте (см. stackoverflow.com/a/41266715/6408646). - person Max Polezhaev; 13.10.2017
comment
Я ответил на этот вопрос, но сервер django останавливается, и я не могу получить доступ к файлу localhost:8000. пожалуйста, проверьте мой вопрос: stackoverflow.com/questions/66417806/ - person Shahriar.M; 01.03.2021