2015-07-20 110 views
2

我正在阅读一本书“Node.js in Action”,并尝试使用它的示例。其中一个例子是从“net”创建一个频道,然后为所有连接创建一个频道,并将消息广播到其他连接/频道。从输入流CLI读取数据 - NodeJS

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 

和您可以从多个终端/外壳连接到在本地主机端口8888上运行的此服务器,但是当涉及从telnet读取输入流时 - 只要用户输入它就会读取数据。所以如果我想用回车符和换行符(\ r \ n)来检测字符串“shutdown”,我不能这样做,因为回调函数在每次击键时都会被调用,所以你得到的是“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

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

LINEMODE,telnet发送你只有在按下输入键入但它被禁用,每个按键发送马上。

所以,这个问题与Node.js或你的代码无关,而是telnet客户端。

您可以使用 mode linemode character两个选项之间进行切换。

+0

在Windows上telnet客户端只有以下选项“设置模式控制台”或“设置模式流” - 它们都不起作用。 https://technet.microsoft.com/en-us/library/Bb491013.aspx 尝试使用“SET crlf”,但没有运气。 – Dharmavir

+0

你可以尝试'设置crlf'? –

+0

是的,我没有设置crlf,但没有运气。 看起来像Windows默认的远程登录客户端有这个问题,我试着用腻子,它的作品像一个魅力,但不知道如何使Windows默认客户端使其工作。无论我使用命令行还是使用PowerShell而不是Putty,结果都是相同的。 :) – Dharmavir