重新连接net.socket nodejs

时间:2014-09-11 15:27:31

标签: node.js sockets

我是node.js的新手,想要连接到TCP套接字。为此,我正在使用网络模块。

我的想法是将连接序列包装到一个函数中然后在'close'事件上,尝试重新连接。显然不那么容易。

function conn() {

    client.connect(HOST_PORT, HOST_IP, function() {
        startSequence();
    })
}

client.on('close', function(e) {
    log('info','Connection closed! -> ' + e)
    client.destroy();
    setTimeout(conn(),1000);
});

因此,当远程主机关闭时,我看到我的日志正在通过,看起来似乎正在发生的事情是,当远程主机上的安卓在线时所有先前的尝试都开始被处理 - 如果这是有道理的。如果你看一下client.connect,就会有一个名为startSequence的函数,它发送一些从远程服务器端“启动”连接的数据。当服务器脱机并且我开始重新连接之前的所有失败尝试似乎已经被缓冲并且在服务器上线时全部一起发送。

我已尝试过此Stackoverflow链接中的代码,但无效(Nodejs - getting client socket to try again after 5 sec time out

client.connect(HOST_PORT, HOST_IP, function() {
    pmsStartSequence();
})


// Add a 'close' event handler for the client socket
client.on('close', function(e) {
    log('debug','connection  closed -> ' + e)
    client.setTimeout(10000, function() {
        log('debug', 'trying to reconnect')
        client.connect(HOST_PORT, HOST_IP, function() {
            pmsStartSequence();
        })
    })
});

有关如何在失败后重新连接套接字的建议吗?

8 个答案:

答案 0 :(得分:7)

问题在于您设置了on-connect回调。

The doc of socket.connect()说:

  

connectListener ...将作为'connect'事件的监听器添加一次。

通过在socket.connect()调用中设置它,每次尝试重新连接时,都会将另一个调用startSequence()的侦听器(一次性)附加到该套接字。在重新连接成功之前,这些听众不会被解雇,因此您可以在一次连接上同时触发所有这些听众。

一种可能的解决方案是将connect侦听器与socket.connect()调用分开。

client.on('connect', function() {
    pmsStartSequence();
});

client.on('close', function(e) {
    client.setTimeout(10000, function() {
        client.connect(HOST_PORT, HOST_IP);
    })
});

client.connect(HOST_PORT, HOST_IP);

答案 1 :(得分:4)

我的解决方案:

var parentHOST = '192.168.2.66';
var parentPORT = 9735;

var net = require('net');
var S = require('string');
var parentClient = new net.Socket();
var parentActive = false;

var startParentClient = function () {
    parentClient = new net.Socket();
    parentActive = false;

    parentClient.connect(parentPORT, parentHOST, function() {
      console.log('Connected ' + cluster.worker.id + ' to parent server: ' + parentHOST + ':' + parentPORT);
      parentActive = true;
    });

    parentClient.on('error', function() {
      parentActive = false;
      console.log('Parent connection error');
    });

    parentClient.on('close', function() {
      parentActive = false;
      console.log('parent connection closed');
      setTimeout(startParentClient(), 4000);
    });
  }

如果有必要连接:

  if (!S(parentHOST).isEmpty() && !S(parentPORT).isEmpty()) {
    startParentClient();
  }

答案 2 :(得分:2)

受其他解决方案的启发,我写了这个,经过测试,它有效! 它将继续每5秒尝试一次,直到连接完成,如果它也失去连接也能正常工作。

/* Client connection */
/* --------------------------------------------------------------------------------- */

const client = new net.Socket()
var intervalConnect = false;

function connect() {
    client.connect({
        port: 1338,
        host: '127.0.0.1'
    })
}

function launchIntervalConnect() {
    if(false != intervalConnect) return
    intervalConnect = setInterval(connect, 5000)
}

function clearIntervalConnect() {
    if(false == intervalConnect) return
    clearInterval(intervalConnect)
    intervalConnect = false
}

client.on('connect', () => {
    clearIntervalConnect()
    logger('connected to server', 'TCP')
    client.write('CLIENT connected');
})

client.on('error', (err) => {
    logger(err.code, 'TCP ERROR')
    launchIntervalConnect()
})
client.on('close', launchIntervalConnect)
client.on('end', launchIntervalConnect)

connect()

答案 3 :(得分:1)

我使用以下代码实现与node.js的重新连接。我不是Javascript专家,所以我想它可以改进,但它对我来说工作正常。 我希望这可以有所帮助。 最好的。

//----------------------------------------------------------------//
// SocketClient                                                   //
//----------------------------------------------------------------//
var net = require('net');

var SocketClient = function(host, port, data_handler, attempt)
{
    var node_client;
    var attempt_index = (attempt ? attempt : 1);

    this.m_node_client = new net.Socket();
    node_client = this.m_node_client;
    this.m_node_client.on('close', function()
    {
        var new_wrapper = new SocketClient(host, port, data_handler, attempt_index + 1);

        node_client.destroy();
        new_wrapper.start();
    });
    this.m_node_client.on('data', data_handler);
    this.m_node_client.on('error', function(data)
    {
        console.log("Error");
    });
    this.start = function()
    {
        this.m_node_client.connect(port, host, function()
        {
            console.log('Connected ' + attempt_index);
        });
    };
};

//----------------------------------------------------------------//
// Test                                                           //
//----------------------------------------------------------------//
var test_handler = function(data)
{
    console.log('TestHandler[' + data + ']');
};
var wrapper = new SocketClient('127.0.0.1', 4000, test_handler);

wrapper.start();

答案 4 :(得分:1)

正如评论中多次提到的那样,在尝试将客户端重新连接到服务器之前,您需要使用.removeAllListeners()以避免同一事件上有多个侦听器。

下面的代码应该可以解决问题

请注意,我尝试在closeend事件之后重新连接客户端,因为在关闭连接后可以以不同的顺序触发这两个事件

const net = require("net")

let client = new net.Socket()

function connect() {
    console.log("new client")
    client.connect(
        1337,
        "127.0.0.1",
        () => {
            console.log("Connected")
            client.write("Hello, server! Love, Client.")
        }
    )

    client.on("data", data => {
        console.log("Received: " + data)
    })

    client.on("close", () => {
        console.log("Connection closed")
        reconnect()
    })

    client.on("end", () => {
        console.log("Connection ended")
        reconnect()
    })

    client.on("error", console.error)
}

// function that reconnect the client to the server
reconnect = () => {
    setTimeout(() => {
        client.removeAllListeners() // the important line that enables you to reopen a connection
        connect()
    }, 1000)
}

connect()

答案 5 :(得分:0)

我尝试通过使用以下方法重新使用相同的套接字连接:

const s = net.createConnection({port});

s.once('end', () => {
    s.connect({port}, () => {

    });
});
从服务器端的角度来看,

无效。如果客户端连接关闭,则创建新连接似乎是最佳做法:

const s = net.createConnection({port});

s.once('end', () => {
    // create a new connection here
    s = net.createConnection(...);
});

悲伤但真实的笑话。

答案 6 :(得分:0)

this之后:

//
// Simple example of using net.Socket but here we capture the
// right events and attempt to re-establish the connection when
// is is closed either because of an error establishing a
// connection or when the server closes the connection.
//

// Requires
const net = require('net');

// Create socket
const port = 5555;
const host = '127.0.0.1';
const timeout = 1000;
let retrying = false;

// Functions to handle socket events
function makeConnection () {
    socket.connect(port, host);
}
function connectEventHandler() {
    console.log('connected');
    retrying = false;
}
function dataEventHandler() {
    console.log('data');
}
function endEventHandler() {
    // console.log('end');
}
function timeoutEventHandler() {
    // console.log('timeout');
}
function drainEventHandler() {
    // console.log('drain');
}
function errorEventHandler() {
    // console.log('error');
}
function closeEventHandler () {
    // console.log('close');
    if (!retrying) {
        retrying = true;
        console.log('Reconnecting...');
    }
    setTimeout(makeConnection, timeout);
}

// Create socket and bind callbacks
let socket = new net.Socket();
socket.on('connect', connectEventHandler);
socket.on('data',    dataEventHandler);
socket.on('end',     endEventHandler);
socket.on('timeout', timeoutEventHandler);
socket.on('drain',   drainEventHandler);
socket.on('error',   errorEventHandler);
socket.on('close',   closeEventHandler);

// Connect
console.log('Connecting to ' + host + ':' + port + '...');
makeConnection();

答案 7 :(得分:0)

function createServer() {
  const client = new net.Socket();

  client.connect(HOST_PORT, HOST_IP, function() {
    console.log("Connected");
    state = 1 - state;
    client.write(state.toString());
  });

  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");
    //client.connect()
    setTimeout(createServer, 2000);
  });
}

createServer();