Node.js的ReadLine不等待一个完整的线路套接字连接?

我想用一个套接字来使用Node.js的ReadLine ,就像这样:

var net = require('net'); var rl = require('readline'); this.streamServer = net.createServer(function (socket) { var i = rl.createInterface(socket, socket); i.on('line', function (line) { socket.write(line); }); }); this.streamServer.maxConnections = 1; this.streamServer.listen(7001); 

当我远程login到端口7001并开始input文本时,在我按下input之前立即回显给我。

为什么ReadLine不等待整行?

我也试过.question()并得到相同的结果…callback是在接收任何数据时被触发,而不等待行尾字符。


编辑:这变得更奇怪。 当我使用Windows telnet客户端进行testing时,我得到了上面所述的行为。 但是,如果我使用PuTTY作为客户端进行testing,则即使在Windows上,ReadLine也可以正常工作。 我做了一些数据包捕获。 也许有人可以对此有所了解? 不缩进的行是来自客户端的数据。 缩进行是服务器回复。

使用Windows Telnet

 00000000 61 a 00000000 61 a 00000001 62 b 00000001 62 b 00000002 63 c 00000002 63 c 00000003 64 d 00000003 64 d 00000004 65 e 00000004 65 e 00000005 66 f 00000005 66 f 00000006 67 g 00000006 67 g 00000007 68 h 00000007 68 h 00000008 69 i 00000008 69 i 00000009 6a j 00000009 6a j 0000000A 6b k 0000000A 6b k 0000000B 6c l 0000000B 6c l 0000000C 6d m 0000000C 6d m 0000000D 6e n 0000000D 6e n 0000000E 6f o 0000000E 6f o 0000000F 70 p 0000000F 70 p 00000010 0d 0a .. 00000010 0d 0a .. 00000012 0d 0a .. 00000012 0d 0a .. 00000014 0d 0a .. 00000014 0d 0a .. 00000016 61 a 00000016 61 a 00000017 73 s 00000017 73 s 00000018 64 d 00000018 64 d 00000019 66 f 00000019 66 f 0000001A 0d 0a .. 0000001A 0d 0a .. 0000001C 61 a 0000001C 61 a 0000001D 73 s 0000001D 73 s 0000001E 64 d 0000001E 64 d 0000001F 66 f 0000001F 66 f 00000020 0d 0a .. 00000020 0d 0a .. 

使用PuTTY

 00000000 ff fb 1f ff fb 20 ff fb 18 ff fb 27 ff fd 01 ff ..... .. ...'.... 00000010 fb 03 ff fd 03 ..... 00000000 ef bf bd ef bf bd 1f ef bf bd ef bf bd 20 ef bf ........ ..... .. 00000010 bd ef bf bd 18 ef bf bd ef bf bd 27 ef bf bd ef ........ ...'.... 00000020 bf bd 01 ef bf bd ef bf bd 03 ef bf bd ef bf bd ........ ........ 00000030 03 . 00000015 61 62 63 64 65 66 67 abcdefg 0000001C 0d 0a .. 00000031 61 62 63 64 65 66 67 abcdefg 00000038 0d 0a .. 0000001E 61 73 64 66 asdf 00000022 0d 0a .. 0000003A 61 73 64 66 asdf 0000003E 0d 0a .. 00000024 61 73 64 66 asdf 00000028 0d 0a .. 00000040 61 73 64 66 asdf 00000044 0d 0a .. 0000002A 0d 0a .. 00000046 0d 0a .. 

这是node.js中的一个错误,ReadLine的Interface调用每个'data'事件的_normalWrite(),_normaWrite有一个注释,它应该尝试在换行符上打破,但是目前它只是调用_onLine() 。

沿着这个线应该为你解决这个问题:

 i._normalWrite = function(b) { if(b == undefined) { return; } if(!this._line_buffer) { this._line_buffer = ''; } this._line_buffer += b.toString(); if(this._line_buffer.indexOf('\n') !=-1 ) { var lines = this._line_buffer.split('\n'); // either '' or the unfinished portion of the next line this._line_buffer = lines.pop(); lines.forEach(function(line) { this._onLine(line + '\n'); }, this); } }; 

我没有testing过,也可能需要考虑\r 。 请让我知道它是否适用于您,如果是的话,那么我们中的一个人应该向它发送一个拉请求。

一个替代的解决scheme,我的问题…我只是需要得到某种线事件,每当有一个新的一行stream。 由于我不需要readline附带的所有内容,所以我在这里find了TooTallNate的这个片段: https ://gist.github.com/1785026

 /** * By TooTallNate, originally posted at https://gist.github.com/1785026 * A quick little thingy that takes a Stream instance and makes * it emit 'line' events when a newline is encountered. * * Usage: * ‾‾‾‾‾ * emitLines(process.stdin) * process.stdin.resume() * process.stdin.setEncoding('utf8') * process.stdin.on('line', function (line) { * console.log(line event:', line) * }) * */ function emitLines (stream) { var backlog = '' stream.on('data', function (data) { backlog += data var n = backlog.indexOf('\n') // got a \n? emit one or more 'line' events while (~n) { stream.emit('line', backlog.substring(0, n)) backlog = backlog.substring(n + 1) n = backlog.indexOf('\n') } }) stream.on('end', function () { if (backlog) { stream.emit('line', backlog) } }) } 

这是作为一个评论纳森的拉请求在这里: https : //github.com/joyent/node/pull/3059