2015-07-20 5 views
2

Я читаю книгу «Node.js в действии» и примеряю примеры из нее. Один из примеров, который создает канал из «сети», а затем создает канал для всех подключений и передает сообщения другим каналам/каналам.Чтение данных из входного потока 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 - он считывает данные, как только пользователь вводит их. Поэтому, если я хочу обнаружить строку «shutdown» с возвратом каретки и строкой строки (\ r \ n), я не могу этого сделать, потому что функция callback вызывается с каждым нажатием клавиши, так что вы получаете «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 отправляет то, что вы набираете, только при нажатии enter, но с отключенным, каждое нажатие клавиши сразу отправляется.

Итак, проблема не имеет ничего общего с Node.js или вашим кодом, кроме клиента telnet.

Вы можете использовать mode line и mode character для переключения между этими двумя вариантами.

+0

на клиентском компьютере telnet клиент имеет только следующую опцию «консоль режима установки» или «поток режима установки» - ни одна из них не работает. https://technet.microsoft.com/en-us/library/Bb491013.aspx Пробовал с «SET crlf», но не повезло. – Dharmavir

+0

Можете ли вы попробовать 'set crlf'? –

+0

Да, я сделал «set crlf», но не повезло.! Похоже, что у клиента telnet по умолчанию Windows эта проблема, я попробовал с помощью шпатлевки, и он работает как шарм, но не уверен, как сделать клиент по умолчанию для Windows, чтобы он работал. Тот же результат, если я использую командную строку или powershell, но замазка работает.! :) – Dharmavir

Смежные вопросы