【已解决】Nodejs小白请教一个createConnection 如何自定义timeout的问题

【已解决】Nodejs小白请教一个createConnection 如何自定义timeout的问题

小白请假一个问题

var net = require('net');
var client = net.createConnection(1234, "12.24.212.61");
  client.on('connect', function () {
    console.log('Connected');
  });
  client.on('error', function(e) {
    console.log('client error');
  });
  client.on('end', function() {
    console.log('client disconnected');
  });

大概是这样,如果那个ip地址存在,但是没有监听1234端口,我就可以马上得到一个返回说错误,但是如果那个IP地址根本不存在(比如服务器没开机),那大概会卡在这里30秒才会告诉我timeout, 我查阅了文档这里也不支持timeout设置。

于是我尝试了js自己的settimeout,

setTimeout(function() {
    console.log('Request Timeout.');
    client.end()
  }, 2000);

这样在2秒的时候,我能看到Request Timeout,但是进程仍然卡住不动,不能往下走。 而且我不能用process.end之类的来结束进程,因为我这里会出去一堆请求,要分别处理所以不能马上结束。 不知道我表达得是否清楚? 我希望的是如果IP地址不存在,那2秒后告诉我一个错误,然后结束这个connection


2 回复

当然可以!根据你的描述,你希望在 node.js 中使用 net.createConnection 创建的客户端连接能够在指定的时间内没有响应时超时,并且能够正确地处理这种情况。默认情况下,net.createConnection 并不直接支持设置超时时间,但你可以通过一些技巧来实现这一功能。

以下是一个示例代码,展示了如何为 net.createConnection 设置自定义的超时时间:

var net = require('net');

function createTimeoutClient(host, port, timeout) {
  return new Promise((resolve, reject) => {
    var client = net.createConnection(port, host, () => {
      console.log('Connected');
      resolve(client);
    });

    client.on('error', (err) => {
      console.log('client error:', err.message);
      reject(err);
    });

    client.on('end', () => {
      console.log('client disconnected');
    });

    // 使用定时器来检测超时
    const timeoutId = setTimeout(() => {
      console.log('Request Timeout.');
      client.destroy(); // 关闭连接
      reject(new Error('Request Timeout'));
    }, timeout);

    // 监听连接关闭事件,以便在连接断开时清除定时器
    client.on('close', () => {
      clearTimeout(timeoutId);
    });
  });
}

// 使用示例
createTimeoutClient("12.24.212.61", 1234, 2000)
  .then(client => {
    // 连接成功后的逻辑
    client.write('Hello Server!');
  })
  .catch(err => {
    console.error('Failed to connect:', err.message);
  });

解释

  1. Promise 包装:我们将 net.createConnection 封装在一个 Promise 中,以便我们可以使用 .then().catch() 来处理异步操作的结果。
  2. 超时处理:我们使用 setTimeout 来设置一个定时器,在指定的超时时间内如果没有连接成功,则触发超时错误并关闭连接。
  3. 清理定时器:当连接成功或连接断开时,我们清除定时器,以避免不必要的资源占用。

这样,即使目标主机不存在或端口未开放,你也能够在指定的超时时间内收到错误通知,并继续处理其他请求。


在 Node.js 中,net.createConnection 并没有直接提供 timeout 参数。不过,你可以通过其他方式来实现连接超时的功能。以下是一种常见的做法,使用 socket.setTimeout 方法结合 socket.destroy 来实现超时控制。

var net = require('net');

function createConnectionWithTimeout(port, host, timeout) {
  var client = new net.Socket();

  // 设置超时时间
  client.setTimeout(timeout);

  client.on('connect', function () {
    console.log('Connected');
    // 清除超时定时器
    client.removeListener('timeout', onTimeout);
  });

  client.on('error', function (e) {
    console.log('Client error:', e.message);
  });

  client.on('timeout', onTimeout);

  client.connect(port, host);

  function onTimeout() {
    console.log('Connection timed out after ' + timeout + 'ms');
    client.destroy();
  }

  return client;
}

var client = createConnectionWithTimeout(1234, '12.24.212.61', 2000);

client.on('end', function () {
  console.log('Client disconnected');
});

解释:

  • client.setTimeout(timeout) 设置了一个超时时间,在指定的时间内如果没有触发 connect 或其他事件,将触发 timeout 事件。
  • client.on('timeout', onTimeout) 绑定 timeout 事件的处理函数 onTimeout,该函数会在超时时调用 client.destroy() 来断开连接。
  • connect 事件触发时,移除 timeout 事件监听器,防止连接成功后仍然触发超时事件。

这样可以确保在 IP 地址不存在或者连接超时的情况下,能够及时地通知并关闭连接。

回到顶部