本地MQTT mosquitto实例获得连接ECONNREFUSED 127.0.0.1:1883

问题描述

我试图通过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

@R_502_6433@Y package*.json ./

RUN npm ci

@R_502_6433@Y ./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'

我想念什么?

解决方法

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

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

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

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

,

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

因此,基本上更改此内容:const client = mqtt.connect(“ mqtt:// localhost:1883”);

为此:const client = mqtt.connect(“ mqtt:// broker:1883”);

,

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

当发布者试图通过localhost:1883与经纪人联系时,通常会收到ECONNREFUSED,因此经纪人不在同一个容器中。

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