Nodejs - 让客户端套接字在 5 秒超时后重试

Nodejs - getting client socket to try again after 5 sec time out

本文关键字:超时 重试 客户端 套接字 Nodejs      更新时间:2023-09-26

刚开始在节点上.js编程和编写一个TCP套接字客户端。

我希望客户端连接到服务器。如果服务器不可用(即服务器在约定的端口上不存在),我希望客户端超时并在超时后重新连接。

我有这个代码,但它挂在第二个客户端.connect上。怎么了?

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 9000;
var client = new net.Socket();
client.connect(PORT, HOST, function(){
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    client.write('I am Superman!');
});
client.on('error', function(e) {
    while (e.code == 'ECONNREFUSED') {
        console.log('Is the server running at ' + PORT + '?');`
        socket.setTimeout(1000, function() {
            console.log('Timeout for 5 seconds before trying port:' + PORT + ' again');
        }
        client.connect(PORT, HOST, function(){
            console.log('CONNECTED TO: ' + HOST + ':' + PORT);
            client.write('I am the inner superman');
        });
    }); 
});

更新的代码:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 9000;
var client = new net.Socket();
client.connect(PORT, HOST, function(){
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    client.write('I am Superman');
});
client.on('error', function(e) {
    while (e.code == 'ECONNREFUSED') {
        console.log('Is the server running at ' + PORT + '?');
        client.setTimeout(4000, function() {
            client.connect(PORT, HOST, function() {
                console.log('CONNECTED TO: ' + HOST + ':' + PORT);
                client.write('I am inner Superman');
            });         
            console.log('Timeout for 5 seconds before trying port:' + PORT + ' again');
        });
    }
});
client.on('data', function(data) {
    console.log('DATA: ' + data);
    client.destroy();
});
client.on('close', function() {
    console.log('Connection closed');
});

使用更新的代码,超时似乎不会生效。当我在没有相应服务器的情况下启动此客户端时,结果显示在下面,无需等待 4 秒。

Is the server running at 9000?
Is the server running at 9000?
Is the server running at 9000?
Is the server running at 9000?
…

更新(吠错树?

我回去查看socket.on('error')事件,看到关闭事件在错误发生后立即被调用。因此,代码将关闭 tcp客户端而无需等待 4 秒。有什么更好的主意吗?

你的超时是反向的。

应如下所示:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 9000;
var client = new net.Socket();
client.connect(PORT, HOST, function(){
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    client.write('I am Superman!');
});
client.on('error', function(e) {
    if(e.code == 'ECONNREFUSED') {
        console.log('Is the server running at ' + PORT + '?');
        client.setTimeout(4000, function() {
            client.connect(PORT, HOST, function(){
                console.log('CONNECTED TO: ' + HOST + ':' + PORT);
                client.write('I am the inner superman');
            });
        });
        console.log('Timeout for 5 seconds before trying port:' + PORT + ' again');
    }   
});
client.on('data', function(data) {
    console.log('DATA: ' + data);
    client.destroy();
});
client.on('close', function() {
    console.log('Connection closed');
});

超时后要运行的函数是回调。那是等待执行的那个。

此外,将while更改为if,该条件在单个错误事件期间不会更改。而且您的括号和括号不匹配。

根据我对已接受答案的评论,我发现了使用 .connect 回调与'connect'侦听器的问题。 每次调用 .connect 时,即使连接失败,它也会提示回调(添加侦听器)。 因此,当它最终连接时,所有这些回调都会被调用。 因此,如果您改用.once('connect'..,则不会发生这种情况。 下面是我的项目客户端代码中的日志记录语句,这些语句引导我得出了这一观察结果。

ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
ENOENT
timeout
(node:21061) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connect listeners added. Use emitter.setMaxListeners() to increase limit  
^=== if you timeout and try .connect again eventually you hit this limit
ENOENT
timeout    <==== here is where the connection finally happens
connecting  <====  now all those listener callbacks fire.
connecting
connecting
connecting
connecting
connecting
connecting
connecting
connecting
connecting
connecting

所以试试下面的这个版本

const net = require('net')
const HOST = '127.0.0.1'
const PORT = 9000
const client = new net.Socket()
const connect = () => {client.connect(PORT, HOST)}
client.once('connect', function(){
  console.log('CONNECTED TO: ' + HOST + ':' + PORT)
  client.write('I am Superman!')
})
client.on('error', function(e) {
  if(e.code == 'ECONNREFUSED') {
    console.log('Is the server running at ' + PORT + '?')
    console.log('Waiting for 5 seconds before trying port:' + PORT + ' again')
    setTimeout(connect,5000)
  }
})
connect()
client.on('data', function(data) {
  console.log('DATA: ' + data)
  client.destroy()
})
client.on('close', function() {
  console.log('Connection closed')
})