从输入流CLI读取数据 - NodeJS

时间:2015-07-20 01:06:50

标签: node.js

我正在读一本书" Node.js in Action"并尝试从它的例子。其中一个例子是创建一个来自" net"然后为所有连接创建一个频道,并将消息广播到其他连接/频道。

var events = require('events');
var net = require('net');

var channel = new events.EventEmitter();
channel.clients = {};
channel.subscriptions = {};

channel.on('join', function (id, client) {
    this.clients[id] = client;
    this.subscriptions[id] = function (senderId, message) {
        if (id !== senderId) {
            this.clients[id].write(message);
        }
    };
    this.on('broadcast', this.subscriptions[id]);
});

channel.on('leave', function(id) {
  channel.removeListener('broadcast', this.subscriptions[id]);
  channel.emit('broadcast', id, id + " has left the chat. \n");
});

channel.on('shutdown', function() {
  channel.emit('broadcast', '', "Chat has shut down.!\n");
  channel.removeAllListeners('broadcast');
});

var server = net.createServer(function (client) {
    var id = client.remoteAddress + ':' + client.remotePort;
    //client.on('connect', function () {
    channel.emit('join', id, client);
    //});
    client.on('data', function (data) {
        data = data.toString();
        if(data == "shutdown\r\n") {
            channel.emit('shutdown');
        }
        channel.emit('broadcast', id, data);
    });
    client.on('close', function() {
      channel.emit('leave', id);
    });
});

server.listen(8888);

现在,如果您查看以下代码:

client.on('data', function (data) {
    data = data.toString();
    if(data == "shutdown\r\n") {
        channel.emit('shutdown');
    }
    channel.emit('broadcast', id, data);
});

当您使用以下命令使用telnet连接到此服务器时,它从命令行读取数据:

telnet 127.0.0.1 8888

并且您可以从多个终端/ shell连接到在localhost端口8888上运行的此服务器,但是当它从telnet读取输入流时 - 它会在用户输入数据后立即读取数据。所以如果我想检测一个字符串" shutdown"使用回车符和换行符(\ r \ n)我无法执行此操作,因为每次按键都会调用回调函数,因此您获得的是" s" " H" " U" " T" ......" n"作为单个字符而不是字符串缓冲区。

我在API中读到有流动模式和暂停模式但不知道如何在这里实现它。

在我遇到的书中还有另一个例子,我通过将它与字符代码进行比较并手动缓冲来修复它,直到我遇到回车键,但我期待更好的解决方案,最好是如果node.js有东西提供。

var net = require('net');

var line = '';
var server = net.createServer(function(socket) {
  socket.on('data', function(data) {
    if(data.toString().charCodeAt(0) != 13){
      line += data.toString();
    } else {
      //console.log('OO');
      socket.write(">>");
      socket.write(line);
      socket.write("\r\n");
      line = '';
    }
  });

  socket.once('data', function(data) {
    socket.write("Hey first time I always stay little reluctant..! Lolz!");
  })
});

server.listen(88);

上面的代码是我用于另一个例子的修复,我遇到了类似的问题,但我想知道解决此问题的标准方法。

1 个答案:

答案 0 :(得分:1)

我刚刚尝试了原始代码,它在我的mac上按预期工作。 我怀疑,您的telnet客户端已禁用LINEMODE,并设置为character at a time

LINEMODE中,telnet仅在按Enter键时发送您键入的内容,但禁用后,会立即发送每次击键。

因此,该问题与Node.js或您的代码无关,而与telnet客户端无关。

你可以使用 mode linemode character在两个选项之间切换。