Ответы пользователя по тегу Node.js
  • Почему не работает DELETE в NodeJs?

    Если вы хотите экстрима, можете почитать про флаг --expose-gc.
    Он поможет вам чистить память в нужное время, но не рекомендован для использования в продакшн.
    Ответ написан
    Комментировать
  • Как запускать скрипт Node.js WebSockets под разными прокси?

    Выносим адрес прокси в переменную, дальше по желанию рассчитываем эту переменную в зависимости от окружения или от переданных параметров

    var proxyAddress = process.env.PROXY_ADDRESS;
    
    // node app.js --proxy_address='...'
    var proxyAddress = process.argv[2].split('=')[1];


    Соответственно либо форкаем процесс с нужными аргументами, либо с нужным окружением:
    child_process.fork('app.js', '--proxy_address=...');
    
    child_process.fork('app.js', {
        env: {
            PROXY_ADDRESS: '...'
        }
    });
    Ответ написан
    1 комментарий
  • Что быстрее: websocket или "обычное" соединение?

    Думаю единственной проблемой будет работа с другими сообщениями протокола, пока вы передаете файл. Давно не работал с вебсокетами, но что-то мне подсказывает, что передача файла заблокирует другие сообщения по каналу. Если это для вас критично, у вас есть два способа решения проблемы:
    1. Передавать файл частями.
    2. Передавать файл по другому каналу. Таким каналом может быть отдельный сокет или, внимание, xhr

    Если мое предположение о заблокированном канале ошибочно, то других подводных камней я придумать не могу.

    Помните что в http протоколе за вас уже позаботились о формате передачи файлов (вспоминаем про multipart/form-data, как об одном из решений), в сокетах вы будете создавать велосипед.
    Ответ написан
    Комментировать
  • Какой Web-фреймворк для Node.js выбрать?

    Посмотрите в сторону loopback. https://github.com/strongloop/loopback
    Вот уж кто позволит вам на лету менять базки.
    И админка у него есть.
    Обна беда - он все-таки больше позицианирует себя как REST.
    Ответ написан
    1 комментарий
  • Балансер - NodeJS или Nginx?

    3y3
    @3y3 Автор вопроса
    Итак для истории:

    Особой разницы, с точки зрения производительности, при использовании балансера Nginx против NodeJS нет.

    Мы сравнивали нашу старую архитектуру построенную с использованием strong-cluster-control c балансировкой через NodeJS, и новую на основе luster с балансировкой на Nginx.
    В обоих случаях был поднят кластер на cpu-1 процессов (в данном случае 32-1)
    В случае luster каждый процесс слушает свой unix сокет, балансировка внутри ноды отключена. В Nginx создан апстрим на эти самые 31 сокет с балансировкой least_connect.

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

    В стрельбах с постоянной нагрузкой на реальном проекте были замечены незначительные отклонения потребления system и user CPU как в одну так и в другую сторону.
    В стрельбах на отказ стабильность повысилась на 5-10%.

    Тестируемое приложение является stateless middleware с преимущественно асинхронными операциями, период простоя в одном стеке не больше 5 мс. Приложение на данный момент не занимается рендерингом шаблонов.

    Для приложений с тяжелыми синхронными операциями (с периодом простоя в стеке больше 50мс) был получен совет использовать следующую архитектуру:
    Все так же поднимаем кластер на cpu-1, но настраиваем luster на меньшее количество групп, например по 4 воркера в каждой группе, т.е. 4 воркера будут слушать один сокет.
    Балансировку в ноде все так же отключаем. Получаем предварительную балансировку least_connect средствами Nginx и дополнительную балансировку средствами системы, которая будет делать выбор опираясь на готовность процесса к чтению из сокета.
    Ответ написан
    Комментировать
  • Как отслеживать прогресс Promise?

    Прогресс не просто так убрали из Promise, в большинстве случаев это антипаттерн.
    Нужно понимать что Promise A+ спроектированы так, чтобы инкапсулировать внутри себя всю связанную с операцией логику.
    Именно поэтому я не советую вам придумывать код, который требует методов Promise.progress, Promise.cancel или свойств Promise.isFullfilled, Promise.isRejected.

    Т.е. вы все еще можете пользоваться этими свойствами, но только не в контексте A+.
    Берите Q или любую легковесную замену, и реализуйте все что хотите через defer.
    Примером того, что вы получите в итоге может являться ответ @onqu

    Приведенный им код полностью отвечает вашей задаче, но вместо того чтобы иметь логический юнит внутри каждого промиса, у вас появляется расшаренное состояние, которое вы можете поменять в любом месте - удачи в отладке.

    Отменяйте промис только внутри него. Сообщайте об изменении состояния только с помощью then. Если вам нужно отслеживать прогресс загрузки чего либо, делайте это через события или каллбеки:

    function doSomethingAsync(timeout, cb) {
      var ee = new EventEmitter();
      var state = {
        progress: 0
      };
    
      (function loop() {
        if (state.progress === 22) return cb(null, state);
        if (state.progress === 'canceled') return cb(new Error('Action canceled'));
        if (state.progress * 1000 > timeout) return cb(new Error('Action timed out'));
    
        ee.emit('progress', state);
        setTimeout(loop, 1000);
      })();
    
      return ee;
    }
    
    
    function a20SecAction(actions = {}) {
      var maxActionTime = 20000;
    
      return new Promise((resolve, reject) => {
        var actionWithProgress = doSomethingAsync(maxActionTime, (err, result) =>
          (err ? reject : resolve)(err || result)
        );
    
        actionWithProgress.on('progress', actions.progress);
      });
    }
    
    a20SecAction({
      progress: (state) => console.log('state:', state.progress)
    }).then(
      (res) => console.log('state: ready'),
      (err) => console.log('state:', err)
    );


    Итак, если у вас есть действие, которое в любом случае должно завершиться, но вам нужно отслеживать прогресс (например загрузки файла), то не пытайтесь решить это на уровне промиса (A+) он вам не подойдет.
    В моем примере три этапа:
    1) Некоторая простейшая асинхронная функция оформленная в nodejs стиле, т.е. она принимает набор параметров и каллбек вида function (err, result) {}
    Это ваш минимальный строительный блок
    2) Функция обертка - более высокий уровень, на котором мы начинаем работать с промисом. Как параметры функция принимает обработчики дополнительных событий нашей операции. В данном случае у операции одно дополнительное событие progress, и два основных - fullfilled, rejected.
    3) Задаем обработчики для всех событий, основные обрабатываем в then, дополнительные через заданные параметры.
    В данном случае я оставил возможность влиять на процесс выполнения извне, внутри обработчика progress. Но лишь для демонстрации того, что это в принципе возможно. На практике лучше не допускать ситуации, когда изменение состояния асинхронной операции происходит извне:
    a20SecAction({
      progress: (state) => {
        console.log('state:', state.progress);
        if (state.progress === 7) state.progress = 'canceled';
      }
    }).then(
      (res) => console.log('state: ready'),
      (err) => console.log('state:', err)
    );


    Ну и в заключении, если у вас уже есть внешняя библиотека, которая предоставляет вам обычный промис для действия, которое может длиться 20 сек, а вам нужно иметь возможность наблюдать за прогрессом - меняйте библиотеку.
    Ответ написан
    2 комментария
  • Как в Node.JS правильно использовать callback?

    Если вы хотите оставить эту прелестную вложенность в коде, то можно так

    var images = {};
            for (var i in news.items) {
                if(typeof news.items[i].attachments !== undefined) {
                    for (var j in news.items[i].attachments)
                        if (news.items[i].attachments[j].type == 'photo') {
                            download(news.items[i].attachments[j].photo.photo_604, 'tmp/' + url.parse(news.items[i].attachments[j].photo.photo_604).pathname.split('/').pop(), function(i, j) {
                                fs.readFile('tmp/' + url.parse(news.items[i].attachments[j].photo.photo_604).pathname.split('/').pop(), function(err, data) {
                                    console.log(checksum(data, 'sha1'));
                                });
                            }.bind(i, j));
                        }
                }
            }


    Или так:
    var images = {};
    Object.keys(news.items).forEach(function(key) {
        var item = news.items[key];
        if (!Array.isArray(item.attachments)) return;
    
        item.attachments.forEach(function(attachment) {
            it (attachment.type !== 'photo') return;
    
            var loc_path = 'tmp/' + url.parse(attachment.photo.photo_604).pathname.split('/').pop();
            download(attachment.photo.photo_604, loc_path, function() {
                fs.readFile(loc_path, function(data) {
                    console.log(checksum(data, 'sha1'));
                });
            });
        });
    });


    Это минимум, который нужен чтобы код стал читаемым.
    Дальше я не могу понять зачем вы сначала скачиваете файл в файловую систему, и потом грузите его в память, почему бы сразу не грузить в память.
    Так же рекомендую использовать промисы вместо каллбеков - это сделает код еще более читабельным.
    Ответ написан
    1 комментарий
  • Возможно ли в node.js зашифровать исходный код?

    Ну могу предложить вам примерный путь.

    1. Пишем C++ аддон, который будет шифровать и расшифровывать js файлы с заданным ключем.
    2. Добавляем новый extension в require.extensions. Например encjs:

    var decrypt = require('my_addon').decryptor('private-key');
    require.extensions['encjs'] = function (m, filename) {
        m._compile(decrypt(filename), filename);
    };


    Разрабатываем приложение на js, конечным пользователям отдаем encjs.
    Ответ написан
    Комментировать
  • Как установить более свежую версию nodejs???

    index0h , kale , оставьте свой Windows hate при себе.

    Gasherez , я так понимаю ваша цель все-таки работа через nvm-windows, а не просто обновление версии nodejs.
    В этом случае, главное что вам надо сделать - удалить путь к папке nodejs из PATH. Опционально можете удалить саму папку.
    Так же могу посоветовать обновить npm до последней версии.
    Ответ написан
  • Как правильно устанавливать node аддоны с нативным кодом?

    По поводу рабочего окружения:
    Я бы порекомендовал уйти от Win XP хотя бы на Win 7. Из личного опыта - если вдруг у вас возникнет проблема с установкой модуля на Win XP никто даже не почешется помочь вам с отладкой.
    Так же я порекомендовал бы Visual Studio 2010 или 2013. Здесь в большинстве случаев разницы не будет. После выбора используемой версии советую прописать npm config set msvs_version 2013 (или 2010 соответственно)
    Стоит ознакомиться с рекомендациями приведенными в инструкции по работе с node-gyp

    Установка нативых модулей в iojs это отдельная песня. Шанс что они скомпилируются как подмодули какого-то проекта нулевой, поскольку node-gyp не умеет компилировать под iojs, потому что не знает откуда качать его исходники. Поэтому Вам скорее всего придется устанавливать эти модули отдельно, компилировать их, а потом кидать в папку проекта.
    Для компиляции используйте npm install -g pan-gyp. Это форк node-gyp созданный специально для компиляции под iojs. Собственно для компиляции модуля:
    1. берем его с гитхаба
    2. в package.json в секцию scripts прописываем preinstall: pan-gyp rebuild. (В случае модуля с которым вы мучаетесь, перезаписываем сразу install script)
    3. Из директории модуля запускаем npm install .

    У некоторых нативных модулей действительно есть скомпилированные бинарники, но это целиком ответственность разработчика модуля. И ответственность притом не малая. В случае вашего модуля, такие бинарники отсутствуют. Чаще всего при наличии бинарников у модуля в зависимостях будет висеть node-pre-gyp. (Примеры v8-profiler, v8-debug).
    К слову для приведенных примеров вам совершенно необязательно что-либо перезаписывать.
    Эти два модуля являются подмодулями node-inspector и в большинстве случаев устанавливаются без проблем.

    В заключении:
    Если не хотите вздрагивать при появлении в зависимостях проекта нативных модулей, то советую действительно использовать nodejs, так как компиляция под iojs еще очень не стабильна в плане инструментов.

    Модуль, с которым вы мучаетесь, скорее всего вообще не тестировался на iojs.
    Так же обратите внимание на package.json engine в этом пректе.
    Ответ написан
    1 комментарий
  • Как заставить Node JS Выполнять код по порядку?

    В поддержку совета Тимур Шемсединов, вот вам код:

    var async = require('async');
    
    var queries = ['query_1', 'query_2'],
        result = '';
    
    async.reduce(
      queries, 
      result, 
      function iterator(result, query, callback) {
        connection.query("SELECT  " + query, function(err_photo, rows_photo, fields) {
          if (err_photo) callback(err_photo);
    
          for (var k=0; k < rows_photo.length; k++) {
            result += 'Записываем значение 2 запроса';
            console.log('1');
          }
    
          callback(null, result);
        })
      },
      function done(error, result) {
        console.log(error, result);
      }
    );


    Также прошу вас отформатировать код в вашем вопросе.
    Ответ написан
    1 комментарий
  • Как узнать о завершении выполнения кода модуля в Node.JS?

    Если уж вы серьезно собираетесь писать PHP подобный сервер, то мой вам совет почитайте про vm модуль, он бы вам пригодился.

    Но честно говоря вы создали себе проблему на пустом месте, потому что сменили язык программирования, но не сменили идеологию мышления.
    Ответ написан
    2 комментария
  • Как в NodeJS сделать EventEmitter для нескольких одновременных запросов?

    Я советую вам посмотреть в сторону обещаний.
    Начните с канонической библиотека promise
    Когда разберетесь с ней, вам возможно потребуется комбайн посложнее, смотрите в сторону Q

    // npm install promise
    
    var fs = require('fs');
    var Promise = require('promise');
    
    // В качестве источника данных в данном случае файловая система,
    // в вашем случае это видимо будет net.Connection
    function dataStoredLoad( dataName ) {
        return new Promise(function(resolve, reject) {
            fs.readFile(dataName, 'utf8', function(err, data) {
                if (err) return reject(err);
    
                resolve(data);
            });
        })
    }
    
    // Это другой способ записать то, что написано в dataStoredLoad
    function dataSourceLoad( dataName ) {
        return Promise.denodeify(fs.readFile)(dataName, 'utf8');
    }
    
    Promise.all(dataStoredLoad, dataSourceLoad).then(function(res) {
        var stored = res[0],
              sourse = res[1];
    
        stored.forEach( function (dataStored, index) {
            sourse.forEach( function (dataStored, index) {
                if ( dataStored.id == dataSource ) {
                     // key.value comparsion procedure and .pop() / .push()
                }
            }
        }
    });
    Ответ написан
    1 комментарий
  • Где ошибка в gruntfile.js?

    Вы забыли запятые:
    }, // <-- Запятая
      //Сжатие
      uglify: {
        build: {
          src: 'production/js/script.js',
          dest: 'production/js/script.min.js'
        }
      }
    Ответ написан
    2 комментария
  • Как правильнее объявить exports чтобы каждый раз его не писать в js?

    Ммм... Возможно вы ищете
    module.exports = {
      findById: function() {},
      findAll: function() {}
    }
    Ответ написан
    1 комментарий
  • На сколько верно задуман routes в nodejs(express)?

    В общем и целом, если вы не хотите изобретать велосипед, посмотрите на уже готовые обдуманные реализации. Например Loopback, который в контексте вашего вопроса является оберткой над express. Эти ребята уделили достаточно времени обсуждению того, как должен храниться rest api
    Ответ написан
  • Выбор back-end фреймворка?

    Насколько я знаю, expressjs перешел под крыло StrongLoop. Поскольку их основной продукт Loopback целиком и полностью завязан на express, я бы не стал волноваться за его будущее.
    Сами по себе Strongloop это опытная команда разработчиков, работающая в том числе и над "Node core". Я имею удовольствие взаимодействовать с ними в проекте node-inspector.

    Я кстати не рекомендовал бы вам использовать чистый экспресс, если вы собираетесь делать, что-то большое. Экспресс это все-таки еще библиотека, а не фреймворк.

    В ответ на ваш вопрос я бы порекомендовал как раз Loopback.
    Ответ написан
    Комментировать
  • EventEmitter и а-синхронность?

    Сам по себе EventEmitter.emit - синхронная функция, что может многих удивить.
    process.on('ev', function() {
      console.log('ev');
    });
    (function() {
      console.log('a');
      process.emit('ev');
      console.log('b');
    } ());
    //a
    //ev
    //b

    Но на этом синхронность заканчивается. Т.е. например если process.on('ev', cb) был вызван не столь тривиально и в нескольких местах в асинхронном коде, я бы не советовал вам даже пытаться понять какой из cb будет вызван первым. Я не утверждаю, что у вас не получится вычислить последовательность вызова, но говорю что вычислять ее в корне неправильно - это антипаттерн. Если вы хотите быть уверенным в последовательности вызова используйте коллбеки или промизы, но не события.
    Ответ написан
    5 комментариев
  • Конкатинация CSS/JS при помощи gulp и как переподключение в файле index.html?

    Есть несколько вариантов решения.
    1. В лоб - создаем еще один index.html, кладем его в папку predefined, при сборке копируем оттуда в папку build. Естественно в этом файле прописаны только пути для сжатой версии. Такой вариант подойдет, если index это единственный html файл, и других различий в нем не будет.
    2. Используем шаблонизатор - например jade, или любой другой поддерживающий include. Компилируем шаблоны на этапе сборки.

    Вообще я бы порекомендовал не работать над не собранным проектом. Т.е. лучше сразу настроить все watch-еры для автоматической пересборки, и в браузере смотреть только на результат. В противном случае, могут появиться ситуации, когда скрипт сборки сильно просрочен по сравнению с проектом, потому что не было необходимости постоянно собирать проект.

    Другими словами относитесь к сборщику (если уж решились его использовать), так же как и к тестам - это часть проекта, а не внешнее необязательное окружение.
    Ответ написан