刚开始使用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秒。有更好的想法吗?
答案 0 :(得分:7)
你的超时是相反的。
应该是这样的:
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
,在单个错误事件期间该条件不会更改。你的parens和括号不匹配。
答案 1 :(得分:3)
根据我对已接受答案的评论,我发现使用.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')
})