Локальный экземпляр MQTT mosquitto получает отказ от подключения 127.0.0.1:1883

#docker #docker-compose #mqtt #mosquitto

#docker #docker-создать #mqtt #mosquitto

Вопрос:

Я пытаюсь запустить настройку локального брокера mosquitto, издателя и подписчика через docker и docker-compose, но издатель не может подключиться к брокеру. Однако подключение к локальному брокеру через cli работает нормально. При запуске ниже настройки получаю следующую ошибку.

 { Error: connect ECONNREFUSED 127.0.0.1:1883
  at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1088:14)
  errno: 'ECONNREFUSED',
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 1883 }
  

Локальная настройка в dockerized:

docker-compose.yml:

 version: "3.5"

services:
  publisher:
    hostname: publisher
    container_name: publisher
    build:
      context: ./
      dockerfile: dev.Dockerfile
    command: npm start
    networks:
      - default
    depends_on:
      - broker

  broker:
    image: eclipse-mosquitto
    hostname: mosquitto-broker
    container_name: mosquitto-broker
    networks:
      - default
    ports:
      - "1883:1883"

networks:
  default:
  

dev.Dockerfile:

 FROM node:11-alpine

RUN mkdir app
WORKDIR app

COPY package*.json ./

RUN npm ci

COPY ./src ./src

CMD npm start

  

src/index.js:

 const mqtt = require("mqtt");

const client = mqtt.connect("mqtt://localhost:1883");

client.on("connect", () => {
  console.log("Start publishing...");
  client.publish("testTopic", "test");
});

client.on("error", (error) => {
  console.error(error);
});
  

Однако, если я подключаюсь к брокеру mosquitto через mqtt-js cli, он работает так, как ожидалось. Например.
mqtt sub -t 'testTopic' -h 'localhost' и mqtt pub -t 'testTopic' -h 'localhost' -m 'from MQTT.js' .

Чего мне не хватает?

Ответ №1:

ваш контейнер publisher и брокер работают в двух разных контейнерах, что означает, что это две разные машины, каждая из которых имеет свой собственный IP.

вы не можете вызвать службу брокера из своего контейнера publisher с помощью localhost: 1883 и наоборот, из контейнера broker в publisher

Чтобы получить доступ к контейнеру брокера, вы должны вызвать IP-адрес контейнера, или имя, или название службы

в вашем случае измените mqtt.connect("mqtt://localhost:1883"); значение на mqtt.connect("mqtt://broker:1883"); и попробуйте

Ответ №2:

publisher И broker выполняются в разных контейнерах, что означает, что у них разные IP-адреса.

Когда издатель пытается связаться с брокером по адресу localhost:1883 , обычно получает ECONNREFUSED , следовательно, брокер не находится в том же контейнере.

Вы должны заменить 127.0.0.1 или localhost именем службы брокера ( broker в данном случае). Имя службы будет преобразовано в правильный IP-адрес контейнера брокера.

Ответ №3:

в вашем index.js вы должны изменить «localhost» на «broker». Когда внутри контейнера «localhost» будет разрешен для этого конкретного контейнера, поэтому вы всегда должны использовать вместо этого имя службы, а docker позаботится о маршрутизации к этой конкретной службе. Также по умолчанию все службы в одном и том же файле компоновки добавляются в одну сеть, поэтому нет необходимости указывать это.

Итак, в основном измените это: const client = mqtt.connect(«mqtt://localhost:1883»);

Для этого: const client = mqtt.connect(«mqtt://брокер: 1883»);

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

1. Спасибо за дополнительную подсказку о конфигурации сети