Подключиться к брокеру MQTT с помощью Websocket
В последние годы, с быстрым развитием веб-интерфейса, постоянно появляются новые функции браузеров, в то время как все больше и больше приложений могут быть реализованы на стороне браузера с помощью механизма рендеринга браузера. Также широко используется WebSocket, метод мгновенного обмена данными для веб-приложений.
WebSocket — это протокол компьютерной связи, обеспечивающий полнодуплексные каналы связи по одному TCP-соединению. Протокол WebSocket был стандартизирован IETF как RFC 6455 в 2011 году, а API WebSocket в Web IDL стандартизируется W3C.
Глава 6 протокола MQTT определяет условия, которым должен соответствовать MQTT для передачи через WebSocket [RFC6455] связи и здесь подробно не обсуждается.
Сравнение двух клиентов
Paho.mqtt.js
Транслировать — это проект клиента MQTT от Eclipse, а клиент Paho JavaScript — это одна из библиотек на основе браузера, которая использует WebSockets для подключения к серверу MQTT. По сравнению с другой библиотекой подключения JavaScript, она имеет меньше функций и не рекомендуется.
MQTT.js
MQTT.js — это полностью открытая клиентская библиотека для протокола MQTT, написанная на JavaScript и доступная для Node.js и браузеров. На стороне Node.js его можно установить через глобальную установку и подключить через командную строку. Кроме того, он поддерживает соединения MQTT/TCP, MQTT/TLS, MQTT/WebSocket. Стоит отметить, что MQTT.js также имеет хорошую поддержку программы WeChat Mini.
В этой статье для объяснения соединений WebSocket будет использоваться библиотека MQTT.js.
Установите MQTT.js
Если на вашем компьютере установлена среда выполнения Node.js, вы можете установить MQTT.js напрямую с помощью команды npm.
Установить в текущий каталог
npm install mqtt --save
Ссылки CDN
Или используйте адреса CDN напрямую без установки
<script src="
<script>
// Globally initializes an mqtt variable
console.log(mqtt)
</script>
Подключиться к брокеру MQTT
В этой статье будет использоваться бесплатный публичный MQTT-брокер предоставлено EMQX. Этот сервис создан на базе EMQX Облачная платформа Интернета вещей MQTT. Информация о доступе к брокеру следующая:
- Маклер: Broker.emqx.io
- TCP-порт: 1883 г.
- Порт веб-сокета: 8083
EMQX использует порт 8083 для обычных подключений и 8084 для WebSocket через TLS.
Для простоты поместим подписчика и издателя в один и тот же файл.
const clientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)
const host="ws://broker.emqx.io:8083/mqtt"
const options = {
keepalive: 60,
clientId: clientId,
protocolId: 'MQTT',
protocolVersion: 4,
clean: true,
reconnectPeriod: 1000,
connectTimeout: 30 * 1000,
will: {
topic: 'WillMsg',
payload: 'Connection Closed abnormally..!',
qos: 0,
retain: false
},
}
console.log('Connecting mqtt client')
const client = mqtt.connect(host, options)
client.on('error', (err) => {
console.log('Connection error: ', err)
client.end()
})
client.on('reconnect', () => {
console.log('Reconnecting...')
})
Адрес подключения
Адрес ссылки, продемонстрированный выше, можно разделить на: ws:
// broker
. emqx.io
: 8083
/mqtt
То есть protocol
// host name
. domain
: port
/ path
Новички могут совершать следующие ошибки.
- В адресе подключения не указан протокол: WebSocket — это коммуникационный протокол, который использует
ws
(не зашифровано),wss
(зашифровано SSL) в качестве идентификатора протокола. клиент MQTT.js поддерживает несколько протоколов, и в адресе подключения должен быть указан тип протокола. - В адресе подключения не указан порт: MQTT не указывает порт для доступа через WebSocket, а EMQX использует
8083
а также8084
в качестве портов по умолчанию для незашифрованных и зашифрованных соединений соответственно. Порт по умолчанию протокола WebSocket такой же, как HTTP (80/443), отсутствие порта означает, что WebSocket использует порт по умолчанию для подключения. С другой стороны, нет необходимости указывать порт при использовании стандартного соединения MQTT. Например, MQTT.js может использоватьmqtt://localhost
на стороне Node.js для подключения к стандартному порту MQTT 1883, а когда адрес подключенияmqtts://localhost
он будет подключен к порту 8884. - Адрес подключения без пути: MQTT-WebSoket единообразно использует
/path
в качестве пути подключения, который следует указать при подключении, а путь, используемый на EMQX,/mqtt
. - Протокол не соответствует порту: используйте
wss
подключение, но подключение к порту8083
. - Использование незашифрованных соединений WebSocket в рамках HTTPS: такие организации, как Google, продвигают HTTPS, одновременно ограничивая безопасность через ограничения браузера, т. е. использование незашифрованного
ws
протокол для инициирования запросов на подключение автоматически запрещается браузером при HTTPS-соединениях. - Сертификат не соответствует адресу подключения: длинный, подробности см. ниже Включить SSL/TLS для EMQX.
Варианты подключения
В приведенном выше коде options
это параметры подключения клиента. Ниже приведено описание основных параметров, остальные параметры см. https://github.com/mqttjs/MQTT.js#клиент.
- keepalive: время сердцебиения, по умолчанию 60 секунд, установите 0 для отключения.
- clientId: идентификатор клиента, который генерируется случайным образом
'mqttjs_' + Math.random().toString(16).substr(2, 8)
по умолчанию. - имя пользователя: имя пользователя подключения (необязательно)
- пароль: пароль подключения (необязательно)
- clean: true, установите значение false, чтобы получать сообщения QoS 1 и 2 в автономном режиме.
- reconnectPeriod: по умолчанию 1000 миллисекунд, интервал между повторными подключениями, дублированием идентификатора клиента, ошибками аутентификации и т. д. Клиент переподключится.
- connectTimeout: по умолчанию 30 * 1000 миллисекунд, время ожидания перед получением CONNACK, т.е. время ожидания соединения.
- will: will message, сообщение, которое Брокер отправит автоматически, когда клиент резко отключится. Общий формат:
- тема: тема для публикации
- полезная нагрузка: сообщение, которое будет опубликовано
- качество обслуживания: качество обслуживания
- сохранить: сохранить знак
Подписки могут быть сделаны только после успешного подключения, а темы, на которые подписаны, должны соответствовать правилам темы подписки MQTT.
Примечание. JavaScript Асинхронная неблокирующая функция JavaScript обеспечивает успешное соединение только после события соединения или с помощью client.connected
чтобы определить, было ли соединение успешным.
client.on('connect', () => {
console.log('Client connected:' + clientId)
// Subscribe
client.subscribe('testtopic', { qos: 0 })
})
// Unsubscribe
client.unubscribe('testtopic', () => {
console.log('Unsubscribed')
})
Публиковать/получать сообщения
Публикуйте сообщения в определенных темах. Опубликованная тема должна соответствовать правилу публикации темы MQTT. В противном случае он отключится. Не нужно подписываться на эту тему перед публикацией, но необходимо убедиться, что клиент уже успешно подключился.
// Publish
client.publish('testtopic', 'ws connection demo...!', { qos: 0, retain: false })
// Received
client.on('message', (topic, message, packet) => {
console.log('Received Message: ' + message.toString() + '\nOn topic: ' + topic)
})
Мини-программа WeChat
Библиотека MQTT.js использует wxs
идентификатор протокола для специальной обработки мини-программы WeChat. Примечание. Спецификация разработки апплета требует использования зашифрованного соединения, а адрес соединения должен быть аналогичен wxs://broker.emqx.io:8084/mqtt
.
Включить SSL/TLS для EMQX
Встроенный самозаверяющий сертификат EMQ, зашифрованное соединение WebSocket запущено по умолчанию, но большинство браузеров сообщают о недопустимых ошибках сертификата, таких как net::ERR_CERT_COMMON_NAME_INVALID
(Chrome, 360 и другие браузеры с ядром WebKit в режиме разработчика. Вкладку «Консоль» можно использовать для просмотра большинства ошибок подключения). Причина этой ошибки в том, что браузер не может проверить действительность самоподписанного сертификата. Читателю необходимо приобрести доверенный сертификат в центре сертификации и обратиться к соответствующему разделу этой статьи для действий по настройке: Включить SSL/TLS для брокера EMQX MQTT.
Условия, необходимые для включения сертификатов SSL/TLS, приведены здесь:
- Привяжите доменное имя к публичному адресу MQTT-брокера: сертификат, выданный центром сертификации, подписывается для доменного имени.
- Подайте заявку на сертификат: подайте заявку на сертификат для доменного имени, используемого с центром сертификации, позаботившись о выборе надежного центра сертификации и о том, что сертификат различает общее доменное имя и имя хоста.
- Выберите
wss
протокол при использовании зашифрованного соединения и использовать доменное имя для подключения : после привязки доменного имени — сертификация, необходимо использовать доменное имя для подключения вместо IP-адреса, чтобы браузер проверял сертификацию по доменному имени, чтобы установить соединение после того, как оно прошло проверку.
Конфигурация EMQX
Открой etc/emqx.conf
файл конфигурации и измените следующие конфигурации:
# wss listening address
listener.wss.external = 8084
# Modify key file address
listener.wss.external.keyfile = etc/certs/cert.key
# Modify certificate file address
listener.wss.external.certfile = etc/certs/cert.pem
Перезапустите EMQX после завершения.
Вы можете использовать свой сертификат и файлы ключей, чтобы заменить их непосредственно в etc/certs/.
Настройка обратных прокси и сертификатов на Nginx
Использование Nginx для обратного прокси-сервера и шифрования WebSocket может снизить вычислительную нагрузку брокера EMQX и одновременно реализовать мультиплексирование доменных имен. Nginx балансировки нагрузки также позволяет вам распределять несколько сущностей внутренних служб.
# It is recommended that WebSocket also bind to port 443.
listen 443, 8084;
server_name example.com;
ssl on;
ssl_certificate /etc/cert.crt; # certificate path
ssl_certificate_key /etc/cert.key; # key path
# upstream server list
upstream emq_server {
server 10.10.1.1:8883 weight=1;
server 10.10.1.2:8883 weight=1;
server 10.10.1.3:8883 weight=1;
}
# Common website application
location / {
root www;
index index.html;
}
# Reverse proxy to EMQX unencrypted WebSocket
location / {
proxy_redirect off;
# upstream
proxy_pass
proxy_set_header Host $host;
# Reverse proxy retains client address
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
# WebSocket extra request header
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
}
Другие источники
Онлайн-инструментарий MQTT WebSocket:
Первоначально опубликовано на