วิธีเชื่อมต่อ Node.js TCP-client ในคอนเทนเนอร์ A กับ TCP-server ในคอนเทนเนอร์ B ด้วย Docker Compose

ฉันกำลังพยายามเชื่อมต่อไคลเอ็นต์ TCP ในคอนเทนเนอร์ A กับเซิร์ฟเวอร์ TCP ในคอนเทนเนอร์ B การเรียกใช้ docker-compose up ส่งผลให้เกิดข้อผิดพลาด ECONNREFUSED ที่ฝั่งไคลเอ็นต์ 为什么呢?

ไคลเอ็นต์ TCP มีลักษณะดังนี้:

   var net = require('net');

var client = new net.Socket();
client.connect(1337, function() {
    console.log('Connected');
    client.write('Hello, server! Love, Client.');
});

client.on('data', function(data) {
    console.log('Received: ' + data);
    // client.destroy(); // kill client after server's response
});

client.on('close', function() {
    console.log('Connection closed');
});

Dockerfile ไคลเอนต์ TCP มีลักษณะดังนี้:

FROM node:latest

RUN mkdir /app
WORKDIR /app

ADD . /app

ADD package.json /app
RUN npm install

EXPOSE 1337

ENV PATH /app/node_modules/.bin:$PATH

CMD npm start

เซิร์ฟเวอร์ TCP มีลักษณะดังนี้:

var net = require('net');

var server = net.createServer(function(socket) {
    socket.write('Echo server\r\n');
    socket.pipe(socket);
});

server.listen(1337);

Dockerfile เซิร์ฟเวอร์ TCP มีลักษณะดังนี้:

FROM node:latest

RUN mkdir /app
WORKDIR /app

ADD . /app

ADD package.json /app
RUN npm install

EXPOSE 1337

ENV PATH /app/node_modules/.bin:$PATH

CMD npm start

docker-compose.yml มีลักษณะดังนี้:

version: "3"
services:
  tcpclient:
    build: ./tcpclient
    ports:
      - "8000:8000"
    depends_on:
      - tcpserver
  tcpserver:
    build: ./tcpserver
    ports:
      - "8001:1337"

ข้อผิดพลาดในการเชื่อมต่อมีลักษณะดังนี้:

tcpclient_1  | > [email protected] start /app
tcpclient_1  | > node tcpclient.js
tcpclient_1  |
tcpclient_1  | events.js:137
tcpclient_1  |       throw er; // Unhandled 'error' event
tcpclient_1  |       ^
tcpclient_1  |
tcpclient_1  | Error: connect ECONNREFUSED 127.0.0.1:1337
tcpclient_1  |     at Object._errnoException (util.js:1003:13)
tcpclient_1  |     at _exceptionWithHostPort (util.js:1024:20)
tcpclient_1  |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1194:14)
tcpclient_1  | npm ERR! code ELIFECYCLE

ความช่วยเหลือจะได้รับการชื่นชมอย่างมาก


person Wasbeer    schedule 01.02.2018    source แหล่งที่มา
comment
127.0.0.1 จะชี้ไปที่ localhost ของคอนเทนเนอร์ของคุณ ไม่ใช่ localhost ของโฮสต์ของคุณ ลองเชื่อมต่อโดยใช้ tcpserver:1337 แทน 127.0.0.1 นักเทียบท่าเขียนจะปรับใช้คอนเทนเนอร์เหล่านั้นตามค่าเริ่มต้นในเครือข่ายเดียวกัน ซึ่งหมายความว่าพวกเขาสามารถแก้ไขซึ่งกันและกันได้โดยใช้ชื่อบริการ   -  person lvthillo    schedule 01.02.2018
comment
โอเค การเพิ่ม 'tcpserver' เนื่องจากโฮสต์ทำงานได้อย่างมหัศจรรย์ ขอบคุณ!   -  person Wasbeer    schedule 01.02.2018
comment
ขณะนี้ไคลเอ็นต์เชื่อมต่อกับเซิร์ฟเวอร์: tcpclient_1 | tcpclient_1 | > [email protected] start /app tcpclient_1 | > node tcpclient.js tcpclient_1 | tcpclient_1 | Connected อย่างไรก็ตาม หลังจากเชื่อมต่อแล้ว ไคลเอ็นต์จะไม่ได้รับข้อมูล สามารถดูโค้ดได้ที่นี่: github.com/wassbeer/docker/tree/networking -ในการเขียน   -  person Wasbeer    schedule 01.02.2018
comment
ฉันไม่ใช่นักพัฒนาโหนด แต่เมื่อฉันยกเลิกหมายเหตุ client.destroy(); ดูเหมือนว่าจะถูกทำลายและพิมพ์การเชื่อมต่อปิดหลังจากได้รับข้อมูล แต่บางทีฉันอาจผิด   -  person lvthillo    schedule 01.02.2018
comment
ปัญหากลายเป็น docker-compose up ไม่ได้บันทึกเอาต์พุตทั้งหมดในกล่องเครื่องมือ Docker เมื่อรัน docker-compose logs --follow tcpclient ฉันสามารถเห็นการสื่อสารระหว่างเซิร์ฟเวอร์และไคลเอ็นต์ทั้งหมด   -  person Wasbeer    schedule 02.02.2018


คำตอบ (1)


ปัญหาหลายประการที่นี่ ฉันไม่แน่ใจว่า localhost จากคอนเทนเนอร์จะอยู่ในอินเทอร์เฟซเดียวกันกับโฮสต์ของคุณ ยิ่งกว่านั้นพอร์ตที่ผูกไว้คือ 8001 แต่ฉันขอแนะนำวิธีอื่น:

การใช้ link คุณสามารถอ้างอิงโฮสต์คอนเทนเนอร์อื่นด้วยชื่อของพวกเขาได้ ฉันจะพยายามที่จะ:

1) เพิ่มใน tcpclient คำจำกัดความคอนเทนเนอร์: links: - tcpserver 2) เก็บ 1337:1337 ไว้ในเซิร์ฟเวอร์ TCP (เหตุใดไคลเอนต์จึงเปิดเผยพอร์ต TCP btw?) 3) ใช้ client.connect(1337, 'tcpserver', function(...){...}

person Jean-Adrien    schedule 01.02.2018
comment
1) ขอขอบคุณ การเพิ่ม 'tcpserver' เป็น HOST ไปยัง client.connect(1337, ....) ทำให้ไคลเอ็นต์เชื่อมต่อ! 2) การเพิ่มลิงก์ดูเหมือนจะไม่เปลี่ยนพฤติกรรม หากไม่มีมันก็ใช้ได้เช่นกัน 3) หลังจากการเชื่อมต่อ ไคลเอนต์จะไม่ได้รับข้อมูล หรือไม่บันทึกสิ่งนี้ เบาะแสใด ๆ ว่าทำไมมันถึงเชื่อมต่อแต่ไม่ได้รับข้อมูล? ขอบคุณ - person Wasbeer; 01.02.2018