Mosquitto TLS устанавливает лимит размера автозагрузки
Я реализовал незащищенного брокера от комаров, который фантастически работает, периодически отправляя большие объемы данных (~200 КБ раз в минуту) через порт 1883.
Поскольку я реализовал TLS, брокер, по-видимому, автоматически отклоняет данные>128 КБ через порт 8883, несмотря на установку message_size_limit = 0
,
вот мой mosquitto.conf:
listener 1883 localhost
listener 8883
certfile /etc/letsencrypt/live/example.com/cert.pem
cafile /etc/letsencrypt/live/example.com/chain.pem
keyfile /etc/letsencrypt/live/example.com/privkey.pem
И вот мой сценарий, который используется для тестирования брокера, который отлично работает без TLS более 1883
client = mqtt.Client("test")
client.tls_set(certfile="./mqtt/cert.pem", keyfile="./mqtt/key.pem")
client.connect("example.com", 8883)
#publish file as zip
with open("./mqtt/20180319171000.gz", 'rb') as f:
byte_array = f.read()
m.update(byte_array)
file_hash = m.hexdigest()
payload_json = {'byte_array': byte_array, 'md5': file_hash}
client.publish("topic", pickle.dumps(payload_json), 0)
time.sleep(1)
client.disconnect()
Есть ли ограничение на размер полезной нагрузки с TLS или что-то не так с моими настройками / сценарием?
2 ответа
Проблема здесь в том, что цикл клиента MQTT не запускается.
Когда полезная нагрузка больше, чем может поместиться в одном TCP-пакете, вызов
Правильный ответ — не увеличивать период проверки активности. Есть 2 способа решить эту проблему с помощью библиотеки python Paho.
Во-первых, вы можете использовать класс Publish вместо класса Client. Сюда входит одна функция, которая обрабатывает все фоновые задачи, необходимые для доставки всего сообщения.
import paho.mqtt.publish as publish
tls_opt = {
'certfile':"./mqtt/cert.pem",
'keyfile':"./mqtt/key.pem"
}
with open("./mqtt/20180319171000.gz", 'rb') as f:
byte_array = f.read()
m.update(byte_array)
file_hash = m.hexdigest()
payload_json = {'byte_array': byte_array, 'md5': file_hash}
publish.single("topic", payload=pickle.dumps(payload_json), qos=0, hostname="example.com", port=8883, tls=tls_opt)
Во-вторых, запустить сетевой цикл следующим образом:
client = mqtt.Client("test")
client.tls_set(certfile="./mqtt/cert.pem", keyfile="./mqtt/key.pem")
client.connect("example.com", 8883)
client.loop_start()
#publish file as zip
with open("./mqtt/20180319171000.gz", 'rb') as f:
byte_array = f.read()
m.update(byte_array)
file_hash = m.hexdigest()
payload_json = {'byte_array': byte_array, 'md5': file_hash}
client.publish("topic", pickle.dumps(payload_json), 0)
time.sleep(1)
client.loop_stop()
client.disconnect()
Старый вопрос, но у меня возникла та же проблема с большими сообщениями (>500 КБ). Мое решение состояло в том, чтобы увеличить время проверки активности на клиенте с (по умолчанию) 60 до 300 секунд.
Это, вероятно, связано с тем, что время ожидания для шифрования TLS для больших сообщений занимает больше времени, чем поддержка активности.
Изменить: добавлен код python для подключения:
client.connect(
host="example.com",
port=8883,
keepalive=300)
Обновление: я нашел этот вопрос в поисках ответов на проблему, похожую на мою, а именно: публикация MQTT не удалась для больших (>500 КБ) полезных лодов при использовании MQTT TLS. Как указывает @hardillb в своем ответе, OP отсутствует
client.loop_start()
. Однако это не решает мою проблему.
не должно влиять, но это не так. Увеличение значения определенно устраняет проблему. Моя теория заключается в том, что брокер прерывает соединение по тайм-ауту, потому что он пытается отправить PING клиенту, но клиент отказывается отвечать, потому что он занят попыткой зашифровать сообщение. Впрочем, это всего лишь теория.
Я создал тестовый код, чтобы проиллюстрировать проблему. Я также включил «последнюю волю», чтобы проверить, потеряно ли соединение без надлежащего разъединения (), и это, кажется, соответствует моей теории. Использование слишком малого значения определенно активирует последнюю волю к брокеру, указывая на «тайм-аут».
Увеличение не активирует «последнюю волю» у брокера.
Вот мой код, который я использовал для тестирования различных значений и размеров полезной нагрузки.
import paho.mqtt.client as mqtt_client
import time
from datetime import datetime
password = 'somepassword'
user = 'someuser'
address = 'somebroker.no'
connected = False
def on_connect(client, userdata, flags, rc):
global connected
connected = True
print("Connected!")
def on_disconnect(client, userdata, rc):
global connected
connected = False
print("Disconnected!")
client = mqtt_client.Client()
client.username_pw_set(user, password)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.tls_set()
client.will_set(topic='tls_test/connected', payload='False', qos=0, retain=True)
client.connect(host=address, port=8883, keepalive=100)
client.loop_start()
while not connected:
time.sleep(1)
topic = 'tls_test/abc'
payload = 'a'*1000000
start = time.time()
print('Start: {}'.format(datetime.fromtimestamp(start).strftime('%H:%M:%S')))
result = client.publish(topic='tls_test/connected', payload='True', qos=0, retain=True)
result = client.publish(topic=topic, payload=payload)
if result.rc != 0:
print("MQTT Publish failed: {}".format(result.rc))
exit()
client.loop_stop()
client.disconnect()
stop = time.time()
print('Stop: {}, delta: {} sec'.format(datetime.fromtimestamp(stop).strftime('%H:%M:%S'), stop-start))
Используя приведенный выше код (
keepalive=100
), он отправляет 1000000 байт и имеет значение
True
на брокера после окончания. Данные успешно переданы, вывод консоли:
python3 .\mqtt_tls.py
Connected!
Start: 10:51:16
Disconnected!
Stop: 10:53:01, delta: 105.57992386817932 sec
Уменьшение активности (
keepalive=10
), передача не удалась и
tls_test/connected
имеет значение
False
на брокера после окончания. Передача данных не удалась, и вывод консоли:
python3 .\mqtt_tls.py
Connected!
Start: 11:08:23
Disconnected!
Disconnected!
Stop: 11:08:43, delta: 19.537118196487427 sec
Хвост
/var/log/mosquitto/mosquitto.log
на брокере выдает следующее сообщение об ошибке:
1612346903: New client connected from x.x.x.x as xxx (c1, k10, u'someuser').
1612346930: Socket error on client xxx, disconnecting.
Мой вывод таков:
keepalive
влияет на большие полезные нагрузки при использовании TLS