Здравствуйте, Буравчик, Вы писали:
S>>Кто-нибудь работает с протоколом MQTT? Б>Что нужно-то?
Вопрос в следующем. Насколько я понимаю принципы MQTT, каждый топик может хранить единственное значение (ну или единый форматированный набор). То есть, если писатель, допустим датчик температуры, помещает в топик очередное значение, этим он затирает значение, которое записал туда ранее. И читатель, подключившийся позже, должен увидеть только последнее значение.
А у меня происходит странное. В некоторых случаях (не смог установить закономерности, в каких) брокер отдает читателю после его подключения не последнее значение топика, а сразу несколько, последовательно, одно за другим. Более того, несколько раз была ситуация, что брокер впадает в ступор и начинает многократно слать подписавшемуся один и тот же топик с одним и тем же значением, забивая канал и все другие топики. Писатель при этом может быть вообще отключен. Лечится шаманскими плясками или перезагрузкой брокера. Что это?
Все топики публикуются у меня с QoS=1, RETAIN. Я отлаживаю и читателя, и писателя, и, допустим, в процессе экспериментов мог накосячить и посылать брокеру что-то не то. Но не могу понять, что именно. Что послать брокеру, что он впадает такое состояние, ибо в целом все работает, проблема случается лишь изредка.
Когда брокер начинает повторять один и тот же топик, пробовал посылать ему и PUBACK, и PUBREC, и PUBREL, и PUBCOMP (хотя для QoS=1 это все вроде как не нужно) — это брокер не останавливает (писатель, напоминаю, при этом м.б. отключен). Как сказать брокеру, что читатель топик уже получил, и больше посылать его не надо?
Здравствуйте, sz36, Вы писали:
S> Вопрос в следующем. Насколько я понимаю принципы MQTT, каждый топик может хранить единственное значение (ну или единый форматированный набор). То есть, если писатель, допустим датчик температуры, помещает в топик очередное значение, этим он затирает значение, которое записал туда ранее. И читатель, подключившийся позже, должен увидеть только последнее значение.
Вообще говоря нет. Мне тут приходилось полгода назад делать слепую интеграцию, когда я писал код вслепую, знал только что протокол. Отправлял исходники, их проверяли на отсутствие закладок неделю и через неделю мне присылали логи, если не то, то повторял, так надо мной не издевались никогда в жизни до этого, мне блин даже Hello world кода не дали, а когда я написал эмулятор сервера, выяснилось блин что я не тот протокол использую, и повторно уже не было времени сервер-эмулятор писать . Заработало со второго раза, в первый раз выяснилось что на стороне сервера формат данных не соответствует тому, как было обещано . Я юзал Paho client, и это блин единственное, что мне сказали что можно использовать для интеграции, типа они юзают это, больше у меня инфы вообще не было. Так вот, там не последнее значение, у меня был clientid, и когда я подключался, то мне приходили изменения с последнего подключения. И именно это у меня заработало сразу же, у меня там были некоторые проблемы что я пишу в базу медленнее, чем приходят данные, пришлось делать всякие хитрости чтоб сгладить пики, плюс у библиотеки крайне хреновое API и пришлось несколько поизвращаться чтоб корректно восстанавливался реконнект в случае если сервер перезагружили или была сетевая проблема. Но именно концепция с самого начала работала как очередь.
А то, что ты сказал — так kafka работает, когда ты именно забираешь, и если без некоторых хитростей, то ты будешь забирать последнее значение. В случае с MQTT все выглядит так (по крайней мере API так в библиотеке доступа выглядит), как будто данные тебе кидают, и это именно фича этой шины.
Здравствуйте, sz36, Вы писали:
S> Вопрос в следующем. Насколько я понимаю принципы MQTT, каждый топик может хранить единственное значение (ну или единый форматированный набор). То есть, если писатель, допустим датчик температуры, помещает в топик очередное значение, этим он затирает значение, которое записал туда ранее. И читатель, подключившийся позже, должен увидеть только последнее значение.
Нет, каждый топик не обязательно должен хранить единственное значение. Более того, сообщения внутри топика могут иметь абсолютно разные форматы. Хотя, в основном, через топик идут сообщения одного формата, и получателю обычно важно только последнее сообщение (но не всегда).
S> А у меня происходит странное. В некоторых случаях (не смог установить закономерности, в каких) брокер отдает читателю после его подключения не последнее значение топика, а сразу несколько, последовательно, одно за другим. Более того, несколько раз была ситуация, что брокер впадает в ступор и начинает многократно слать подписавшемуся один и тот же топик с одним и тем же значением, забивая канал и все другие топики. Писатель при этом может быть вообще отключен. Лечится шаманскими плясками или перезагрузкой брокера. Что это?
MQTT-сервер пытается передать подписчикам новые сообщения. Если подписчик в некоторый момент недоступен, то сервер сохранит эти сообщения, ожидая подключения подписчика. При подключении подписчика сервер отправляет ему сохраненные сообщения. Не только одно последнее, а все сообщения, пришедшие в топик.
На это влияет две вещи: во-первых clientId — по нему он идентифицирует клиента и определяет, какие сообщения не доставлены этому клиенту. Во-вторых, при подключении клиента можно установить специальный флаг "clean session" = 1, который заставит сервер "забыть" о предыдущих сообщениях.
S> Все топики публикуются у меня с QoS=1, RETAIN. Я отлаживаю и читателя, и писателя, и, допустим, в процессе экспериментов мог накосячить и посылать брокеру что-то не то. Но не могу понять, что именно. Что послать брокеру, что он впадает такое состояние, ибо в целом все работает, проблема случается лишь изредка.
Подключайся с флагом "clean session" = 1. Тогда ты не будешь получать сообщения, пришедшие во время "отсутствия" подписчика.
К тому же, если будешь публиковать сообщения с "retain", как делаешь сейчас, то сразу после подключения подписчика к серверу тебе будет приходить последнее retain-сообщение (только одно)
Здравствуйте, elmal, Вы писали:
> у меня был clientid, и когда я подключался, то мне приходили изменения с последнего подключения. > Но именно концепция с самого начала работала как очередь.
Это не очень согласуется с моими наблюдениями. Железяка писатель лежит у меня на столе и шлет данные постоянно, некоторые топики обновляются каждые несколько секунд, то есть значений в случае очереди д.б. много. Время от времени я запускаю под отладчиком телефон читатель и он получает только последние значения топиков, я это вижу по логам. Все работает прекрасно.
Проблемы обычно случаются, когда я что-то меняю в писателе, экспериментирую с протоколом, форматом, меняю ClientId и проч. C некоторой вероятностью после этого читатель сходит с ума.
Основной вопрос, собс-но, не в этом. Пусть там будет очередь, не жалко. Как сказать брокеру "горшочек не вари", чтобы он хотя бы не слал многократно одно и то же значение топика?
Здравствуйте, sz36, Вы писали:
S> Основной вопрос, собс-но, не в этом. Пусть там будет очередь, не жалко. Как сказать брокеру "горшочек не вари", чтобы он хотя бы не слал многократно одно и то же значение топика?
Скорее всего ты забываешь подтверждать доставку, соответственно брокер повторяет данные. Деталей не помню . Собственно я в гугле вбил и там на stackoverflow был какой то код, я его потом просто обернул как мне нужно и все. Тебе очень повезло что у тебя есть сервак на поиграться, у меня не было .
Здравствуйте, Буравчик, Вы писали:
Б>Если подписчик в некоторый момент недоступен, то сервер сохранит эти сообщения, ожидая подключения подписчика. При подключении подписчика сервер отправляет ему сохраненные сообщения. Не только одно последнее, а все сообщения, пришедшие в топик.
Я выше уже отвечал, что как-то это странно работает, я не вижу, чтобы брокер всегда отдавал все пропущенные читателем сообщения. Дело в том, что писатель у меня включен практически постоянно, и раз в несколько секунд он что-нибудь, да опубликует. А читателя запускаю изредка, с большими перерывами и по его логу я вижу, что после подключения как правило он получает только одно, последнее значение в каждом топике.
Б>Подключайся с флагом "clean session" = 1. Тогда ты не будешь получать сообщения, пришедшие во время "отсутствия" подписчика.
С clean session я не пробовал, попробую. Но непонятен какой момент — если я подключусь с clean session, гарантировано ли, что я получу последнее, или хотя бы какое-нибудь значение для каждого топика? Или они все очистятся несмотря на RETAIN и нужно ждать следующей публикации?
Б>К тому же, если будешь публиковать сообщения с "retain", как делаешь сейчас, то сразу после подключения подписчика к серверу тебе будет приходить последнее retain-сообщение (только одно)
Этого я как раз и добиваюсь.
Здравствуйте, sz36, Вы писали:
S>Здравствуйте, Буравчик, Вы писали:
S> Я выше уже отвечал, что как-то это странно работает, я не вижу, чтобы брокер всегда отдавал все пропущенные читателем сообщения. Дело в том, что писатель у меня включен практически постоянно, и раз в несколько секунд он что-нибудь, да опубликует. А читателя запускаю изредка, с большими перерывами и по его логу я вижу, что после подключения как правило он получает только одно, последнее значение в каждом топике.
Может от clientid зависеть. Если ты использовал тот же clientid, то сервер вспомнит тебя и выдаст много сообщений. Если ты использовал новый clientid, то сервер будет думать, что ты новый клиент, и выдаст тебе только одно сообщение.
Также может зависеть от того, сообщил ли ты серверу о получении сообщения. Если не сообщил, то он тебе отправит их заново (если узнает тебя по clientid). Или делай subscribe с QoS 0.
Б>>Подключайся с флагом "clean session" = 1. Тогда ты не будешь получать сообщения, пришедшие во время "отсутствия" подписчика. S>С clean session я не пробовал, попробую. Но непонятен какой момент — если я подключусь с clean session, гарантировано ли, что я получу последнее, или хотя бы какое-нибудь значение для каждого топика? Или они все очистятся несмотря на RETAIN и нужно ждать следующей публикации?
Clean session и retain работают независимо друг от друга. Поэтому получишь последнее сообщение даже в случае clean session. Нужно только не забыть отправлять сообщение с retain-флагом.
Здравствуйте, sz36, Вы писали:
S> А у меня происходит странное. В некоторых случаях (не смог установить закономерности, в каких) брокер отдает читателю после его подключения не последнее значение топика, а сразу несколько, последовательно, одно за другим. Более того, несколько раз была ситуация, что брокер впадает в ступор и начинает многократно слать подписавшемуся один и тот же топик с одним и тем же значением, забивая канал и все другие топики. Писатель при этом может быть вообще отключен. Лечится шаманскими плясками или перезагрузкой брокера. Что это?