NodeJS套接字初始化为未暂停?

时间:2014-01-02 19:52:32

标签: node.js

NodeJS中的net.Socket对象是一个可读流,但文档中的一个注释让我担心:

对于Net.Socket 'data'事件,docs say

  

请注意,如果Socket发出'data'事件时没有听众,数据将会丢失

这似乎意味着Socket以“流动模式”返回到调用脚本并且已经取消暂停?但是,对于通用可读流,'data'事件的documentation表示

  

如果你附加一个data事件监听器,那么它会将流切换到流动模式,数据一旦可用就会传递给你的处理程序。

“If”似乎意味着如果你稍等一下绑定到'data'事件,流将等待你,如果你故意想要错过'data'事件,那么{ resume()方法中的{3}}似乎表明您必须调用resume()方法来启动数据流。

我担心的是,在使用net.Server时,如果您在net.Socket事件中收到'connection',那么您是否必须开始处理'data '事件已经开启了吗?我的意思是:

var s = new net.Server();
s.on('connection', function(socket) {
  // Do some lengthy setup process here, blocking execution for a few seconds...
  socket.on('data', function(d) { console.log(d); });
});
s.listen(8080);

意思是不立即绑定到'data'事件,我可能会丢失数据?如果每个设备都需要冗长的设置,那么这是一种处理传入连接的更健壮的方法吗?

var s = new net.Server();
s.on('connection', function(socket) {
  socket.pause(); // Not ready for you yet!

  // Do some lengthy setup process here, blocking execution for a few seconds...

  socket.on('data', function(d) { console.log(d); });
  socket.resume(); // Okay, go!
});
s.listen(8080);

任何人都有使用侦听原始套接字流的经验,以了解此数据丢失是否存在问题?

我希望这是一个自v0.10以来Net.Socket文档没有更新的实例,因为example有一个部分提到'data'个事件在版本中立即开始发送在0.10之前。 TCP套接字是否已正确更新,无法立即开始发送'data'数据包,文档未正确更新?

1 个答案:

答案 0 :(得分:1)

是的,这是文档的缺陷。这是一个例子:

var net = require('net')
var server = net.createServer(onConnection)

function onConnection (socket) {
  console.log('onConnection')

  setTimeout(startReading, 1000)

  function startReading () {
    socket.on('data', read)
    socket.on('end', stopReading)
  }

  function stopReading () {
    socket.removeListener('data', read)
    socket.removeListener('end', stopReading)
  }
}

function read (data) {
  console.log('Received: ' + data.toString('utf8'))
}

server.listen(1234, onListening)

function onListening () {
  console.log('onListening')
  net.connect(1234, onConnect)
}

function onConnect () {
  console.log('onConnect')
  this.write('1')
  this.write('2')
  this.write('3')
  this.write('4')
  this.write('5')
  this.write('6')
}

收到所有数据。如果您明确resume()套接字,则会丢失它。

另外,如果你以阻塞的方式进行“漫长的”设置(你不应该),你就不会丢失任何IO,因为它没有机会被处理,所以不会发出任何事件。