[英]Node.js ReadLine not waiting for a full line on socket connections?
I am trying to use Node.js's ReadLine with a socket , like so: 我试图使用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);
When I telnet into port 7001 and start typing text, it is immediately echoed back to me before I ever push enter. 当我远程登录到端口7001并开始输入文本时,它会在我按下回车之前立即回复给我。
Why is ReadLine not waiting for a full line? 为什么ReadLine不等待全线?
I have also tried .question()
and I get the same results... The callback is fired upon reception of any data, without waiting for an end-of-line character. 我也尝试了
.question()
,我得到了相同的结果......在收到任何数据时触发回调,而不等待行尾字符。
Edit: This gets even stranger. 编辑:这甚至更奇怪。 When I test using the Windows telnet client, I get the behavior that I stated above.
当我使用Windows telnet客户端进行测试时,我得到了上面提到的行为。 However, if I test using PuTTY as the client, ReadLine works, even on Windows.
但是,如果我使用PuTTY作为客户端进行测试,ReadLine即使在Windows上也能正常工作。 I did some packet captures.
我做了一些数据包捕获。 Maybe someone could shed some light on this?
也许有人可以对此有所了解? Unindented lines are data from the client.
未缩进的行是来自客户端的数据。 Indented lines are the server replies.
缩进行是服务器回复。
Using Windows Telnet 使用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 ..
Using PuTTY 使用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 ..
This is a bug in node.js, ReadLine's Interface calls _normalWrite() on each 'data' event and _normaWrite has a comment that it should try to break on newlines, but currently it just calls _onLine() . 这是node.js中的一个错误,ReadLine的接口在每个'data'事件上调用_normalWrite(),而_normaWrite有一个注释,它应该尝试在换行符上打破,但是目前它只调用_onLine() 。
Something along the lines of this should fix it for you: 根据这一点,我们应该为您解决这个问题:
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);
}
};
I haven't tested this, it may need to take \\r
into account also. 我没有测试过这个,它也可能需要考虑
\\r
。 Please let me know if it works for you, if so then one of us should send node a pull request with it. 如果它适用于你,请告诉我,如果是这样,那么我们中的一个人应该发送节点拉取请求。
An alternate solution to my problem... I just needed to get some sort of line event every time there was a new line from a stream. 我的问题的另一种解决方案......每次从流中获得新行时,我只需要获得某种行事件。 Since I didn't need everything else that comes with readline, I found this snippet by TooTallNate here: https://gist.github.com/1785026
由于我不需要readline附带的所有其他东西,我在这里找到了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)
}
})
}
This was posted as a comment to Nathan's pull request here: https://github.com/joyent/node/pull/3059 这是作为对Nathan的拉动请求的评论发布在这里: https : //github.com/joyent/node/pull/3059
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.