【问题标题】:Local MQTT mosquitto instance getting connect ECONNREFUSED 127.0.0.1:1883本地 MQTT mosquitto 实例连接 ECONNREFUSED 127.0.0.1:1883
【发布时间】:2020-08-27 11:31:55
【问题描述】:

我正在尝试通过 docker 和 docker-compose 运行本地 mosquitto 代理、发布者和订阅者设置,但发布者无法连接到代理。但是,通过 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);
});

但是,如果我通过 mqtt-js cli 连接到 mosquitto 代理,它会按预期工作。例如。 mqtt sub -t 'testTopic' -h 'localhost'mqtt pub -t 'testTopic' -h 'localhost' -m 'from MQTT.js'

我错过了什么?

【问题讨论】:

    标签: docker docker-compose mqtt mosquitto


    【解决方案1】:

    您的发布者容器和代理在两个不同的容器中运行,这意味着它们是两台不同的机器,每台机器都有自己的 ip。

    您不能使用 localhost:1883 从您的发布者容器调用代理服务,反之亦然,从代理到发布者容器

    要访问代理容器,您必须调用容器 ip 或名称或服务名称

    在您的情况下,将 mqtt.connect("mqtt://localhost:1883"); 值更改为 mqtt.connect("mqtt://broker:1883"); 并尝试一下

    【讨论】:

      【解决方案2】:

      在您的 index.js 中,您应该将“localhost”更改为“broker”。当在容器中时,“localhost”将解析到该特定容器,因此您应该始终使用服务名称,而 docker 将负责路由到该特定服务。同样默认情况下,同一个撰写文件中的所有服务都添加到同一个网络,因此无需指定。

      所以基本上改变这个: const client = mqtt.connect("mqtt://localhost:1883");

      对此:const client = mqtt.connect("mqtt://broker:1883");

      【讨论】:

      • 感谢网络配置的额外提示
      【解决方案3】:

      publisherbroker 在不同的容器中运行,这意味着它们具有不同的 IP。

      当发布者尝试通过localhost:1883 联系代理时,收到ECONNREFUSED 是正常的,因此代理不在同一个容器中。

      您应该将127.0.0.1localhost 替换为代理的服务名称(在这种情况下为broker)。服务名称将解析为代理容器的正确 IP。

      【讨论】: