0

我正在尝试了解 node.js 中的流!

服务器.js

var net = require("net");

var server = net.createServer(function(conn) {

  conn.write("welcome!");

  # echo the user input!
  conn.pipe(conn);
});

server.listen("1111", function() {
  console.log("port 1111 opened");
});

远程登录测试

服务器当前回显用户的输入

$ telnet localhost 1111
welcome!
hello
hello

期望的输出

为了演示我应该在哪里/如何处理服务器端的流,我想{}在回显之前包装用户的输入

$ telnet localhost 1111
welcome!
hello
{hello}
4

3 回答 3

3

这将基本上完成您要求的确切输出:

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)结束。我们检查消息的结尾,看看是否是这种情况。如果不是,那么我们暂时存储来自连接的消息,直到收到换行符。

这对您的应用程序来说可能不是问题,但认为这值得一提。

于 2012-09-26T18:06:01.207 回答
1

你可以做类似的事情

conn.on 'data', (d) ->
  conn.write "{#{d}}"

.pipe 方法基本上只是附加输入流的数据事件以写入输出流

于 2012-09-26T18:01:35.070 回答
0

我不确定 net() 实际上,但我想它与 http 非常相似:

http.createServer(function (req, res) {


        res.writeHead(200, {'Content-Type': 'text/event-stream'});
        http.get(options, function(resp){
            resp.on('data', function(chunk){
                res.write("event: meetup\n");
                res.write("data: "+chunk.toString()+"\n\n");
            });
        }).on("error", function(e){
            console.log("Got error: " + e.message);
        });
});

https://github.com/chovy/nodejs-stream

于 2012-09-26T18:08:19.780 回答