【问题标题】:Nodejs - getting client socket to try again after 5 sec time outNodejs - 让客户端套接字在 5 秒超时后重试
【发布时间】:2018-01-30 16:41:57
【问题描述】:

刚开始在 node.js 编程和编写一个 tcp 套接字客户端。

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

我有这段代码,但它挂在第二个 client.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') 事件,发现错误发生后立即调用了 close 事件。所以代码将关闭 tcpclient 而无需等待 4 秒。有更好的想法吗?

【问题讨论】:

  • 因为您无需等待即可调用 client.connect。把它放在超时函数里面。

标签: javascript node.js sockets


【解决方案1】:

你的超时被逆转了。

应该是这样的:

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,该条件在单个错误事件期间不会改变。而且你的括号和括号不匹配。

【讨论】:

  • 谢谢杰森!我的 socket.setTimeout 方法有问题。 Node.js 抛出错误。我将其更改为 client.setTimeout(4000, function(){...} 并且它只能工作一次,因为 if。我将 if 更改为一段时间,但似乎 4000 的 setTimeout 没有生效。有什么想法吗?
  • 未定义套接字..?
  • 我会更新答案,@OfirAttia,OP 更新了代码来修复其他错误。
  • @extensa5620 它只运行一次,因为在 4 秒内,您不会收到新错误
  • (node) 警告:检测到可能的 EventEmitter 内存泄漏。添加了 11 个连接侦听器。使用emitter.setMaxListeners() 增加限制。
【解决方案2】:

根据我对已接受答案的评论,我发现了使用 .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')
})

【讨论】:

    猜你喜欢
    • 2011-07-31
    • 2017-06-01
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-27
    • 2013-11-30
    相关资源
    最近更新 更多