понедельник, 11 апреля 2016 г.

[prog.mqtt] Особенности работы wildcard-ов в именах MQTT-шных топиков

Просто оставлю это здесь, т.к. самому через какое-то время вновь потребуется и буду знать где искать.

Метасимвол '#' заменяет любое количество элементов в имени топика. Т.е. подписка на foo/# будет получать сообщения из топиков foo/, foo/bar, foo/bar/baz и т.д.

При этом подписка на foo/# будет приводить так же к получению сообщений из топика foo. Внезапно.

Дело в том, что согласно спецификации MQTT, метасимвол '#' распространяется так же и на родительский элемент: The multi-level wildcard represents the parent and any number of child levels. Т.к. в имени foo/# родительский элемент -- это foo, поэтому топик с именем foo попадает под фильтр foo/#.

Как по мне, так есть здесь что-то корявенькое, ну да ладно. Вполне ожидаемо фильтр # обеспечивает подписку на любой топик. Будь то foo, foo/, foo/bar, foo/bar/, foo/bar/baz и т.д.

А вот фильтр /# работает уже не так. Сообщения из тем foo, foo/, foo/bar и пр. подобных он отслеживать не будет. Тогда как из тем /, /foo, /foo/, /foo/bar и т.д. -- будет. Описание этой особенности удалось отыскать только в одном источнике от IBM. Что не удивительно, т.к. MQTT -- это детище инженеров IBM, а инженерная культура разработчиков из IBM временами производит странное впечатление ;)

С метасимволом '+', который заменяет всего один элемент в имени топика, все гораздо проще. Если есть фильтр foo/+, то он будет отслеживать топики foo/, foo/bar, foo/baz и т.д., но не будет отслеживать топики foo, foo/bar/baz и т.д.

Ну и в довершение. Вот это вот все разные топики: foo, /foo, foo/, /foo/, /foo//.

И, кстати говоря, подряд идущих слешей может быть сколько угодно: ///3/// или ////4////. Причем при работе с такими именами топиков спецификация MQTT запрещает объединять идущие подряд слеши в один. Хотя как по мне, логики здесь гораздо больше, чем в ситуациях с foo/# и foo :)

Комментариев нет: