Страницы

вторник, 7 января 2014 г.

Открытка на Node.js.

Как приготовить оригинальное поздравление с праздником, что называется "своими руками". В финале изложения получим веб-приложение, которое будет раздавать наше поздравление не менее оригинальным, на мой взгляд, способом. Кого не интересует процесс приготовления, можно сразу клонировать репозиторий на GitHub. Результат, назовем его "открытка", может выглядеть примерно так:


"Открытка" состоит из изображения в виде текста в кодировке ascii и произвольного текста поздравления. Для приготовления нам понадобится Node.js.

Для начала выберем изображение. Можно взять уже готовое или преобразовать свое.
И то и другое найдем в google по запросу типа "ascii picture".
Я просто преобразовал свой аватар и сохранил текст в файл по имени che.txt.
                ,#@@@@..              
              @@@@@@@@@@@             
            `@@@@@@@@@@@@@@:          
            @@@@@@@ @@@@@@@@@@        
           @@@@@@@@@@@@@@@@@@@@       
          .@@@@@@@@@@@@@@@@@@@@@      
          :@@@@@@@@@@@@@@@@@@@@@:     
          @@@@@,      `+@@@@@@@@@     
          @@@#            #@@@@@@@    
          @@@               @@@@@@.   
          #@@               :@@@@@+   
          @@@ @@';:   @@@@@, @@@@@#   
          @@@ :.@@@: ;@@@@@@@@@@@@'   
         @@@@ #@#,@  :@@@@@@@@@@@@.   
       +@@@@; +      @+ :@@@@@@@@@`   
       @@@@@`        @    ++@@@@@@'   
      ':@@@@                '@@@@@+   
       @@@@@.     `  .      @@@@@@@@  
       @@@@@'     ,,@@@.   @@@@@@@@'  
       @@@@@@        @   ,@@@@@@@@@:  
       @@@@@@        @@  ;'@@@@@@@@:  
       @@@@@@;  .# .:'@@@`@@@@@@@@@:  
     ,#,+@@@@;  :@#:,:@@@@@@@@@@@@@:  
      :  @@@@@: .    ,@@@@@@@@@@@@@   
      #':@@@@@@    @@@@@@@@@@@@@@@@   
       +@@@@@@@        @@@@@@@@@@@#   
      `@@@@@@@@@@      @@@@@@@@@@@    
       ,@@@@@@@@@@'. ;@@@@@@@@@@@@    
     '  @@@@@@@@@@@@@@@@@@@@@@@@@@    
        , +@@@@@@@@@@@@@@@@@@@@@@'    
          @@@@@@@@@@@@@@@@@@@@@ @     
      ,@,.'@@@@@@@@@@@@@@@@@@@        
           @@@ #@@@@@@@@@@@@@@        

Теперь попробуем прочитать файл che.txt и вывести его содержимое в консоль.
var fs = require('fs');

fs.readFile('./che.txt', {encoding: 'utf8'}, function (err, data) {
  if (err) throw err;
  console.log(data);
});

Выполняем код, получаем изображение команданте в консоли.
Не интересно. Предлагаю раздавать изображение на 23-й порт с тем, чтобы его можно было получить с помощью telnet.
var fs = require('fs'), 
    net = require('net');

var cache = fs.readFileSync('./che.txt', {encoding: 'utf8'});
net.createServer(function (socket) {
  socket.on('error', function() {        
    socket.destroy();
  });
  socket.write(cache);
}).listen(23);

Выполняем код, запускаем telnet:
- telnet localhost

По-моему не хватает динамики.
Прочитаем файл синхронно, разобъем изображение команданте на строки, после чего в переменой cache у нас будет храниться массив. В socket будем писать построчно с интервалом 20 мс.
var fs = require('fs'), 
    net = require('net');

var cache = fs.readFileSync('./che.txt', {encoding: 'utf8'}).split('\r\n');
net.createServer(function (socket) {
  socket.on('error', function() {        
    socket.destroy();
  });
  var i = 0;
  (function cb() {    
    if (i<cache.length) {      
      socket.setTimeout(20, function() {
        socket.write(cache[i] + '\r\n');
        i++;
        cb();
      });
    }
  })();
}).listen(23);

С целью тестирования нашего TCP-сервера, а именно им и является наша "открытка", напишем код клиента, назовем его client.js.
var net = require('net');

var socket = net.connect(23, 'localhost'); 
socket.on('connect', function () {  
  socket.pipe(process.stdout);  
});
socket.on('end', function () {  
  process.exit();
});

Выполняем код сервера, запускаем клиента:
- node client

Остается добавить текст поздравления, предлагаю писать его в socket посимвольно, так "динамичнее" :).
var fs = require('fs'), 
    net = require('net');

var cache = fs.readFileSync('./che.txt', {encoding: 'utf8'}).split('\r\n');
var str = '\r\n\r\n             Happy Holidays!' + 
    '\r\n\r\n           http://www.daspot.ru' + 
    '\r\n         Anatoly Demidovich, 2014\r\n';

net.createServer(function (socket) {
  socket.on('error', function() {        
    socket.destroy();
  });
  var i = 0;
  (function cb() {    
    if (i<cache.length) {      
      socket.setTimeout(20, function() {
        socket.write(cache[i] + '\r\n');
        i++;
        cb();
      });
    } else {
      var j = 0;
      (function cb2() {
        if (j<str.length) {
          socket.setTimeout(20, function() {
             socket.write(str.charAt(j));
             j++;
             cb2();
          });
        }
      })();    
    }
  })();
}).listen(23);

"Открытка" готова. Тестируем.

Теперь можно развернуть приложение в сети и, к примеру с помощью групповой политики, довольно оригинально поздравить своих коллег.

С праздником!