Node.js tcp套接字和链接的Docker容器

Node.js tcp套接字和链接的Docker容器,node.js,sockets,express,tcp,docker,Node.js,Sockets,Express,Tcp,Docker,我在两个Docker容器中有两个节点应用程序 主web应用程序 通过tcp使用套接字的配置文件服务 运行Docker容器时,我使用此选项将配置文件服务容器链接到主Web应用容器 --link srv-profile:srv_profile 它似乎很好地把它联系起来了。我之所以这样说,是因为我能够在我的主web应用程序容器中看到以下内容: root@8d6247a82b6d:/app# echo $SRV_PROFILE_PORT tcp://10.1.0.8:4000 root@8d6247a

我在两个Docker容器中有两个节点应用程序

  • 主web应用程序
  • 通过tcp使用套接字的配置文件服务
  • 运行Docker容器时,我使用此选项将
    配置文件服务
    容器链接到
    主Web应用
    容器

    --link srv-profile:srv_profile
    
    它似乎很好地把它联系起来了。我之所以这样说,是因为我能够在我的
    主web应用程序
    容器中看到以下内容:

    root@8d6247a82b6d:/app# echo $SRV_PROFILE_PORT
    tcp://10.1.0.8:4000
    root@8d6247a82b6d:/app#
    
    我面临的问题是,我的
    主web应用
    容器无法与我的
    配置文件服务
    容器建立连接。以下是我启动主web应用程序时的输出:

    root@8d6247a82b6d:/app# nodemon server.js
    3 Nov 01:22:43 - [nodemon] v1.2.1
    3 Nov 01:22:43 - [nodemon] to restart at any time, enter `rs`
    3 Nov 01:22:43 - [nodemon] watching: *.*
    3 Nov 01:22:43 - [nodemon] starting `node server.js`
    web.main listening on port 4000...
    Connection closed
    
    这是我的
    个人资料服务
    主Web应用程序

    srv profile\server.js

    var net = require('net');
    
    var HOST = '127.0.0.1';
    var PORT = 4000;
    
    // Create a server instance, and chain the listen function to it
    // The function passed to net.createServer() becomes the event handler for the 'connection' event
    // The sock object the callback function receives UNIQUE for each connection
    net.createServer(function(sock) {
    
        // We have a connection - a socket object is assigned to the connection automatically
        console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
    
        // Add a 'data' event handler to this instance of socket
        sock.on('data', function(data) {
    
            console.log('DATA ' + sock.remoteAddress + ':');
            console.log(data);
            console.log();
    
            // Write the data back to the socket, the client will receive it as data from the server
            sock.write('You said "' + data + '"');
        });
    
        // Add a 'close' event handler to this instance of socket
        sock.on('close', function(data) {
            console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
        });
    
    }).listen(PORT, HOST);
    
    console.log('Server listening on ' + HOST +':'+ PORT);
    
    var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
    
    var express             = require('express'),
        logger              = require('morgan'),
        profileManager      = require('./lib/profile-manager');
    
    var app = express();
    
    app.use(logger('dev'));
    
    app.listen(4000, function() {
      console.log('web.main listening on port 4000...');
    
      profileManager.connect();
      profileManager.disconnect();
    });
    
    var net = require('net');
    
    var client = new net.Socket();
    
    var _connect = function() {
        client.connect(process.env.SRV_PROFILE_PORT, function() {
            console.log('CONNECTED TO: ' + process.env.SRV_PROFILE);
    
            // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
            client.write({
                action: 'doSomething',
                data: '1234',
                source: 'web-main'
            });
        });
    
        // Add a 'data' event handler for the client socket
        // data is what the server sent to this socket
        client.on('data', function(data) {
            console.log('DATA: ' + data);
        });
    
        // Add a 'close' event handler for the client socket
        client.on('close', function() {
            console.log('Connection closed');
        });
    };
    
    var _disconnect = function() {
        // Close the client socket completely
        client.destroy();
    };
    
    module.exports = {
      connect: _connect,
      disconnect: _disconnect
    };
    
    webmain\server.js

    var net = require('net');
    
    var HOST = '127.0.0.1';
    var PORT = 4000;
    
    // Create a server instance, and chain the listen function to it
    // The function passed to net.createServer() becomes the event handler for the 'connection' event
    // The sock object the callback function receives UNIQUE for each connection
    net.createServer(function(sock) {
    
        // We have a connection - a socket object is assigned to the connection automatically
        console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
    
        // Add a 'data' event handler to this instance of socket
        sock.on('data', function(data) {
    
            console.log('DATA ' + sock.remoteAddress + ':');
            console.log(data);
            console.log();
    
            // Write the data back to the socket, the client will receive it as data from the server
            sock.write('You said "' + data + '"');
        });
    
        // Add a 'close' event handler to this instance of socket
        sock.on('close', function(data) {
            console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
        });
    
    }).listen(PORT, HOST);
    
    console.log('Server listening on ' + HOST +':'+ PORT);
    
    var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
    
    var express             = require('express'),
        logger              = require('morgan'),
        profileManager      = require('./lib/profile-manager');
    
    var app = express();
    
    app.use(logger('dev'));
    
    app.listen(4000, function() {
      console.log('web.main listening on port 4000...');
    
      profileManager.connect();
      profileManager.disconnect();
    });
    
    var net = require('net');
    
    var client = new net.Socket();
    
    var _connect = function() {
        client.connect(process.env.SRV_PROFILE_PORT, function() {
            console.log('CONNECTED TO: ' + process.env.SRV_PROFILE);
    
            // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
            client.write({
                action: 'doSomething',
                data: '1234',
                source: 'web-main'
            });
        });
    
        // Add a 'data' event handler for the client socket
        // data is what the server sent to this socket
        client.on('data', function(data) {
            console.log('DATA: ' + data);
        });
    
        // Add a 'close' event handler for the client socket
        client.on('close', function() {
            console.log('Connection closed');
        });
    };
    
    var _disconnect = function() {
        // Close the client socket completely
        client.destroy();
    };
    
    module.exports = {
      connect: _connect,
      disconnect: _disconnect
    };
    
    web main\lib\profile manager.js

    var net = require('net');
    
    var HOST = '127.0.0.1';
    var PORT = 4000;
    
    // Create a server instance, and chain the listen function to it
    // The function passed to net.createServer() becomes the event handler for the 'connection' event
    // The sock object the callback function receives UNIQUE for each connection
    net.createServer(function(sock) {
    
        // We have a connection - a socket object is assigned to the connection automatically
        console.log('CONNECTED: ' + sock.remoteAddress +':'+ sock.remotePort);
    
        // Add a 'data' event handler to this instance of socket
        sock.on('data', function(data) {
    
            console.log('DATA ' + sock.remoteAddress + ':');
            console.log(data);
            console.log();
    
            // Write the data back to the socket, the client will receive it as data from the server
            sock.write('You said "' + data + '"');
        });
    
        // Add a 'close' event handler to this instance of socket
        sock.on('close', function(data) {
            console.log('CLOSED: ' + sock.remoteAddress +' '+ sock.remotePort);
        });
    
    }).listen(PORT, HOST);
    
    console.log('Server listening on ' + HOST +':'+ PORT);
    
    var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
    
    var express             = require('express'),
        logger              = require('morgan'),
        profileManager      = require('./lib/profile-manager');
    
    var app = express();
    
    app.use(logger('dev'));
    
    app.listen(4000, function() {
      console.log('web.main listening on port 4000...');
    
      profileManager.connect();
      profileManager.disconnect();
    });
    
    var net = require('net');
    
    var client = new net.Socket();
    
    var _connect = function() {
        client.connect(process.env.SRV_PROFILE_PORT, function() {
            console.log('CONNECTED TO: ' + process.env.SRV_PROFILE);
    
            // Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
            client.write({
                action: 'doSomething',
                data: '1234',
                source: 'web-main'
            });
        });
    
        // Add a 'data' event handler for the client socket
        // data is what the server sent to this socket
        client.on('data', function(data) {
            console.log('DATA: ' + data);
        });
    
        // Add a 'close' event handler for the client socket
        client.on('close', function() {
            console.log('Connection closed');
        });
    };
    
    var _disconnect = function() {
        // Close the client socket completely
        client.destroy();
    };
    
    module.exports = {
      connect: _connect,
      disconnect: _disconnect
    };
    

    如果我正确地阅读了您的代码,您的配置文件服务仅在127.0.0.1上侦听。但是,web应用程序正在从另一个IP地址调用。不同的容器有不同的IP。因此,配置文件服务拒绝传入连接,因为它进入了一个无效的IP。

    您是否尝试在本地运行它,没有docker?我自己做了一个练习,发现了多个问题:

    • 如前所述,服务器应绑定到
      0.0.0.0
      以侦听所有接口
    • 服务器的Docker文件必须
      公开4000
      (在您的示例中似乎是这样的,因为链接起作用)
    • Socket.connect()
      不接受docker样式的url(即'tcp://172.17.0.12:4000“),它必须是一个选项对象,如
      {host:'bla',port:'1337'}
      -使用模块解析docker提供的变量
    • 据我所见,您的客户端在启动连接后立即断开连接(调用
      profile manager.js
    • 不能只将对象写入套接字。合理的编码选择是
      JSON.stringify()
    此外,由于通过套接字接收的
    数据
    是一个
    缓冲区
    ,因此使用
    数据。toString('utf-8')
    应产生人类可读的输出

    工作示例可在上找到