这将基本上完成您要求的确切输出:
var net = require('net');
var server = net.createServer(function(c) {
c.setEncoding('utf8');
c.on('data', function(d) {
c.write('{' + d.trim() + '}\n');
});
});
server.listen(9871);
首先让我提请您注意c.setEncoding('utf8')
。这将在连接上设置一个标志,该标志将自动将传入的 Buffer 转换为 utf8 空间中的字符串。这适用于您的示例,但请注意,为了提高 Socket 之间的性能,最好执行 Buffer 操作。
模拟整个.pipe()
将需要更多的代码。
.pipe()
是Stream
原型的一个方法,可以在lib/stream.js
. 如果您查看该文件,您会看到比我上面显示的要多得多的代码。为了演示,这里有一段摘录:
function ondata(chunk) {
if (dest.writable) {
if (false === dest.write(chunk) && source.pause) {
source.pause();
}
}
}
source.on('data', ondata);
首先检查目标是否可写。如果不是,则没有理由尝试写入数据。接下来检查 if dest.write === false
。从文档中:
如果整个数据成功刷新到内核缓冲区,[.write] 返回 true。如果全部或部分数据在用户内存中排队,则返回 false。
由于 Streams 存在于内核空间中,在 v8 内存空间之外,因此可能会通过填满内存(而不仅仅是让节点应用程序崩溃)来崩溃您的机器。因此,检查消息是否已耗尽是一种安全预防机制。如果它还没有完成耗尽,那么源将被暂停,直到drain
事件被发出。这是排水事件:
function ondrain() {
if (source.readable && source.resume) {
source.resume();
}
}
dest.on('drain', ondrain);
现在,我们可以涵盖更多内容,包括如何.pipe()
处理错误、清理自己的事件发射器等,但我认为我们已经涵盖了基础知识。
注意:发送大字符串时,可能会分多个包发送。因此,可能需要执行以下操作:
var net = require('net');
var server = net.createServer(function(c) {
var tmp = '';
c.setEncoding('utf8');
c.on('data', function(d) {
if (d.charCodeAt(d.length - 1) !== 10) {
tmp += d;
} else {
c.write('{' + tmp + d.trim() + '}\n');
tmp = '';
}
});
});
server.listen(9871);
这里我们假设字符串以换行符(\n
或 ascii 字符代码 10)结束。我们检查消息的结尾,看看是否是这种情况。如果不是,那么我们暂时存储来自连接的消息,直到收到换行符。
这对您的应用程序来说可能不是问题,但认为这值得一提。