Я пытаюсь подключиться к MQTT Broker, используя MQTT.js в своем приложении React, но получаю сообщение об ошибке протокола WSS.
Во-первых, мой файл mosquitto.conf:
# mosquitto.conf
pid_file /run/mosquitto/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
log_dest file /var/log/mosquitto/mosquitto.log
include_dir /etc/mosquitto/conf.d
allow_anonymous false
password_file /etc/mosquitto/passwd
listener 3940
protocol mqtt
listener 39393
protocol websockets
listener 3941
protocol mqtt
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key
listener 3942
protocol websockets
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key
И блок кода в моем приложении React:
// some.jsx
useEffect(() => {
let reconnectAttempts = 0;
try {
if (user && !client) {
const host = "ws://my.domain.io:39393"
// const host = "wss://my.domain.io:3942
const options = {
keepalive: 60,
clientId: `${user.username}_${user.id}_${user.tenant}_${Date.now()}`,
username: "username",
password: "password",
clean: true,
rejectUnauthorized: false
};
const mqttClient = mqtt.connect(host, options);
setClient(mqttClient);
console.info("client: ", mqttClient);
mqttClient.on("connect", () => {
console.info("Connected to MQTT broker");
setIsConnected(true);
setIsReconnecting(false);
setIsDisconnected(false);
reconnectAttempts = 0;
});
mqttClient.on("disconnect", () => {
console.info("Disconnected to MQTT broker");
setIsConnected(false);
setIsDisconnected(true);
});
mqttClient.on("close", (err) => {
console.info("Closed connection to MQTT broker", err);
});
mqttClient.on("reconnect", () => {
reconnectAttempts++;
setIsReconnecting(true);
if (reconnectAttempts > 5) {
mqttClient.end();
console.info("Reconnect attempts exceeded. Closing connection to MQTT broker");
setIsConnected(false);
setIsDisconnected(true);
return;
}
console.info("Reconnecting to MQTT broker", reconnectAttempts);
});
mqttClient.on("error", (err) => {
console.info("Error from MQTT broker", err);
});
}
} catch (error) {
console.error("Error connecting to MQTT broker", error);
}
return () => {
if (client) {
console.info("MQTT Hook cleanup")
client.end();
setClient(null);
}
}
}, [user, client]);
Я могу подключиться к хосту mqtts://my.domain.io:3941 на своем локальном устройстве, но не могу подключиться к хосту wss://my.domain.io:3942 в производственной среде, поскольку мне нужно подключиться через HTTPS. Кроме того, я могу подключиться к wss://my.domain.io:3942 и без проблем выполнять операции публикации/подписки, используя Python, MQTT Box и MQTT Explorer.
СС из MQTT Box:
ОБНОВЛЯТЬ:
# some.py
def connect(self):
self.client.on_message = self.on_message
self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.tls_set(cert_reqs=ssl.CERT_NONE)
self.client.username_pw_set(self.username, self.password)
self.client.connect(self.broker, self.port, keepalive=10)
self.client.loop_start()
Мои журналы Mosquitto выглядят следующим образом. Мое серверное приложение, работающее в локальной среде, может подключаться к порту 3941 без сертификата, тогда как мое приложение React может подключаться только к порту 39393 без сертификата.
Когда мое приложение React в производственной среде пытается подключиться к порту 39393, моя консоль показывает:
Когда он пытается подключиться к порту 3942, моя консоль показывает:
Наконец, хотя мое приложение React в производственной среде настроено на порт 39393 или 3942, в моих журналах Mosquitto данные не отображаются.
Итак, я хочу подключить React к MQTT через WSS на моем рабочем сервере.
@Британцы, вы правы, извините, я обновил свой пост.
Страница, обслуживаемая через HTTPS, не сможет подключиться к ws (только wss браузер не позволяет безопасной странице устанавливать небезопасные соединения). Соединение wss не установлено, но вы не указали причину этого на снимке экрана журнала (и это относится к подписке, которая не показана в вашем коде). Пожалуйста, сосредоточьте свой вопрос на том или ином сервере (локальный или производственный); в противном случае все запутается (ваш журнал Mosquitto не совпадает со снимком экрана браузера wss).
@Brits Когда я попытался подключиться к WSS через https, я не смог подключиться, и Mosquitto не смог его зарегистрировать.
На вашем снимке экрана мы видим, что соединение не установлено, но не можем увидеть причину, потому что вы не расширили эти строки.
@Brits Не было ничего описательного, всего несколько названий пакетов.
Пожалуйста, рассмешите меня (трассировка стека часто помогает отследить проблему); информация из вкладки сети также может быть полезна (чтобы посмотреть, какой ответ на запрос wss). Что касается логов Mosquitto, меня интересует только попытка подключения через wss (из браузера, через который была открыта страница https, ничего работать не будет). Обратите внимание, что cafile в конфигурации mosquitto необходим только при использовании клиентских сертификатов (и их невозможно использовать в браузере).
@Brits, я не знаю, в консоли браузера я вижу только имена пакетов, а на стороне Mosquitto не было журналов на стороне браузера для wss, так что мой мозг действительно поджарен.
ОК, поскольку вы приняли ответ, этот вопрос будет считаться решенным...



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


У меня возникла проблема, из-за которой я не мог подключиться к защищенному брокеру MQTT по адресу wss://dash.meetlarry.io:3942 через HTTPS, находясь на сервере React Linux. Шаги, которые я выполнил для решения этой проблемы, следующие:
Сначала я изменил файлы конфигурации Nginx, включив в них MQTT. конфигурация, поскольку на сервере React уже были конфигурации для сертификаты:
# React App Server
server {
server_name my.domain.io;
root /var/www/html/app/build;
index index.html;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/my.domain.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.domain.io/privkey.pem;
location / {
try_files $uri /index.html;
}
location /mqtt {
proxy_pass http://localhost:39393; # Mosquitto WebSocket port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
# Redirect HTTP to HTTPS for React App
server {
listen 80;
server_name my.domain.io;
return 301 https://$host$request_uri;
}
Затем я обновил код в React следующим образом:
const options = {
host: "my.domain.io", // current server name with certificate
port: 443, // port listened by nginx
path: '/mqtt', // location assigned in nginx
protocol: 'wss', // protocol
keepalive: 60,
clientId: `${user.username}_${user.id}_${user.tenant}_${Date.now()}`,
username: "username",
password: "password",
rejectUnauthorized: false
};
const mqttClient = mqtt.connect(options);
setClient(mqttClient);
Далее я обновил конфигурации MQTT на стороне DRF:
class MQTTClient:
def __init__(self, broker, port, username, password):
self.broker = broker
self.port = port
self.username = username
self.password = password
client_id = f"larry_hotline-{random.randint(0, 1000)}"
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id, transport = "websockets")
def connect(self):
self.client.on_message = self.on_message
self.client.on_connect = self.on_connect
self.client.on_disconnect = self.on_disconnect
self.client.tls_set(cert_reqs=ssl.CERT_NONE)
self.client.username_pw_set(self.username, self.password)
self.client.connect(self.broker, self.port, keepalive=10)
self.client.loop_start()
Я запустил свое приложение Django на порту WebSocket 3942, чтобы гарантировать передачу сообщений, и это решило странную проблему.
Причина, по которой я прибег к этому решению, заключается в том, что я пытался сертифицировать IP-адрес моего MQTT-брокера и подключиться, введя этот IP-адрес вместо имени домена через MQTT.js, но обе попытки не увенчались успехом. Я бы предпочел создать специальный сертификат для брокера MQTT и напрямую подключиться к MQTT.js. Если кому-то уже удавалось подключиться таким способом, я был бы очень рад, если бы мне объяснили и этот метод :)
«Я не могу подключиться» — это недостаточно подробностей, чтобы мы могли помочь. Расскажите, пожалуйста, что происходит при попытке подключения (появляется ли ошибка, что отображается на вкладке сети в консоли браузера/инструментах разработки, есть ли что-нибудь в журнале Mosquitto и т. д.). MRE также поможет, поскольку не совсем понятно, где ваш пример кода вписывается в более широкое приложение ( это руководство может помочь).