Ответы пользователя по тегу Node.js
  • Чем вы отлаживаете Node.js и чего вам не хватает?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Мне стыдно, но я должен признаться, что использую для отладки console.trace, console.dir, console.log. Пошаговая отладка мне нужна вообще 2-3 раза в год , а что нужно часто при разработке Impress (сервера приложений), так это наблюдение за структурами памяти внутри процессов. Для чего я использую node-inspector, так это сделать в консоли нечто типа Object.keys(impress.applications.example.cache.files) и получить ["/app/examples/access.js", "/app/examples/request.js", "/app/examples/simple/jsonPost.json/post.js", "/app/end.js", "/app/lazy.js"]. Это удобно, но вот брекпоинт поставить на обработчик приложения под Impress или где-то в системном коде Impress, мне ни разу не удалось: обработчики вылетают где-попало в системных библиотеках ноды (events, stream, net, fs) в каких-то местах, совершенно не относящихся к тому брекпоинту, которые я ставил. Если использовать cluster/fork Impress не запускается, но слава Аллаху, что у меня есть режим 'single', при котором все происходит в одном процессе и так как-то можно покопаться в памяти. Когда мы допилим Impress до стабильной версии и выпустим доки, то я собирался выделить время и разобраться в отладке, покопаться в этих проблемах и, возможно, что-то соптимизировать специально для совместимости. Вообще спасибо за работу, иногда очень пригаждается!
    Ответ написан
    3 комментария
  • Как создать запрос с декрементом?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Делайте инкремент на -1
    Ответ написан
    Комментировать
  • Как работать с запущенным Node.js приложением через коммандную строку?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Вам нужно сделать два приложения, одно - сервис, второе - CLI, а между ними передавать информацию через один из таких способов: HTTP (самое простое и удобное, но нужно реализовать защиту урлов управления или по секретному ключу или по IP или через аутентификацию), через шину сообщений (от Redis, ZMQ, RabbitMQ и т.д.), через файлы конфигурации (CLI пишет в файлы, а сервис мониторит изменения через fs.watch), через IPC и есть еще куча способов.
    Есть и второй способ, Вы можете у HTTP сервера своего нодовского сделать еще и встроенный telnet сервер или ssh сервер и подключаться к нему консолью, как я это люблю. Вот тут человек делает нечто подобное: www.davidmclifton.com/2011/07/22/simple-telnet-ser... Есть даже библиотеки уже тут: https://www.npmjs.com/package/ssh или тут: https://github.com/mscdex/ssh2
    Ответ написан
    1 комментарий
  • Можно ли создать массив ссылок на элемены?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Смотря какого типа массив и какого типа элементы. Если массив строк или чисел, то нельзя, а если массив объектов, то можно:
    var objArray = [
      { name: "abc" }, { name: "def" },
      { name: "ghi" }, { name: "jkl" }
    ];
    var objArrayLinks = [ objArray[0], objArray[3] ];
    
    console.dir({
      objArray: objArray,
      objArrayLinks: objArrayLinks
    });
    
    objArrayLinks[0].name = "mno";
    
    console.dir({
      objArray: objArray,
      objArrayLinks: objArrayLinks
    });

    Вывод будет:
    { objArray:
       [ { name: 'abc' },
         { name: 'def' },
         { name: 'ghi' },
         { name: 'jkl' } ],
      objArrayLinks: [ { name: 'abc' }, { name: 'jkl' } ] }
    { objArray:
       [ { name: 'mno' },
         { name: 'def' },
         { name: 'ghi' },
         { name: 'jkl' } ],
      objArrayLinks: [ { name: 'mno' }, { name: 'jkl' } ] }

    Скорее всего, Вы хотите сделать индекс в памяти, для этого вообще не нужно массив, а лучше использовать хеш.
    Например:
    var objHash = {
      object1: { name: "abc" },
      object2: { name: "def" },
      object3: { name: "ghi" },
      object4: { name: "jkl" }
    };
    var nameIndex = { abc: objHash.object1, jkl: objHash.object4 };
    
    console.dir({
      objHash: objHash,
      nameIndex: nameIndex
    });
    
    nameIndex["jkl"].name = "mno";
    
    console.dir({
      objHash: objHash,
      nameIndex: nameIndex
    });
    Вывод будет:
    { objHash:
       { object1: { name: 'abc' },
         object2: { name: 'def' },
         object3: { name: 'ghi' },
         object4: { name: 'jkl' } },
      nameIndex: { abc: { name: 'abc' }, jkl: { name: 'jkl' } } }
    { objHash:
       { object1: { name: 'abc' },
         object2: { name: 'def' },
         object3: { name: 'ghi' },
         object4: { name: 'mno' } },
      nameIndex: { abc: { name: 'abc' }, jkl: { name: 'mno' } } }
    Ответ написан
    Комментировать
  • Решение с многопоточностью для node.js?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Можно сделать и в 1 потоке через очереди и асинхронность. Имеем N массивов A1.. AN, стартуем для них в цикле для каждого свой eachSeries, примерно так:
    async.eachSeries(A1, function(item, cb) {
      // сюда приходит item, когда с ним покончено, то делаем cb()
    }, function() {
      // все готово
    });

    Для каждого массива пока предыдущий элемент не отработает (не вернет управление через callback), то следующий не начнет обрабатываться. Если хочется использовать много процессоров, то разделяете задачу на части и запускаете при помощи cluster много процессов, передаявя каждому свою часть работы через переменные окружения или IPC: worker.send.
    Ответ написан
  • Как сделать синхронный цикл в meteor?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Для примера, вместо get будем использовать process.nextTick, который так же с колбеком, просто замените.
    var util = require('util');
    var j = 0;
    function loop() {
      if (++j < 100) {
        console.log(j);
        process.nextTick(loop);
      }
    }
    process.nextTick(loop);
    Ответ написан
  • Как получить результат работы функции с вложенными функциями nodejs?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Что глобальные переменные плохо - это не более, чем расхожее мнение, зачастую сводящееся к религиозному чувству. Приверженцы не могут рационально объяснить, почему именно нельзя. Все доводы о том, что это запутывает код, не выдерживают критики, ведь есть масса примеров, когда введение глобальной переменной наоборот упрощает код и делает его более понятным. Кроме того, в глобальной области видимости лежит куча всего нужного: console, setInterval, clearImmediate, parseInt, Infinity, Math, decodeURI, все встроенные классы и многое другое. Для браузеров еще: document и window. И даже require это глобальная переменная, апологеты почему-то не требуют писать var require = require('require'); Как же так, не порядок, require глобальный. Ересь глобальности затаиласт в самом сердце механизма внедрения зависимостей. На самом деле, не все эти идентификаторы действительно глабальные, и в Node.js могут быть контекты, не будет видно того же require, но сейчас не об этом. А о том, что использование глобальных переменных может давать как полезные, так и вредные плоды. В Вашем случае, вполне можно сделать так:
    // Инициализация глобальной области
    global.model = { // задаем значеня по умолчанию
      alarmId: null // можно поставить, например, -1 или в зависимости от задачи
    };
    // Функция получения 
    function getAlarmId(callback) {
      connection.query('SELECT id from alarm where type=1', function(err, rows, result) {
        if (!err && rows.length === 1) {
          var row = rows[0];
          model.alarmId = row[Object.keys(row)[0]];      
        }
        if (callback) callback();
      });
    }
    // Можем теперь вызвать при старте приложения, обычно без колбека
    getAlarmId();
    // А по ходу исполнения можем вызывать его с колбеком, так и без колбека
    getAlarmId(function() {
      console.dir(model);
    )};
    // Или обновлять по таймеру
    setInterval(getAlarmId, 5000);

    Но лучше всего, не дергать постоянно базу по таймеру или по запросу, а наоборот, сделать основным местом хранения значения - память, и сбрасывать в базу по таймеру, в отложенном режиме, и только если произошли изменения. База нужна нам будет только для постоянного сохранения, операции с ней медленные и асинхронные, а с памятью - быстрые и синхронные. Поэтому, исключив доступ к базе во время обработки HTTP (или других) запросов, мы резко подымаем производительность. Но все это уже не православный REST, а stateful-программирование. Рекомендую почитать еще тут: habrahabr.ru/post/204958 и тут habrahabr.ru/post/247543
    Ответ написан
    Комментировать
  • Io.js обязательно ли использовать ключи для запуска ECMA 6?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    habrahabr.ru/post/247837
    И еще посмотрите вывод: iojs --v8-options|grep "harmony"
    и вот такой вывод: iojs --v8-options | grep "in progress"
    Там будут ключи с пояснениями.
    Ответ написан
    Комментировать
  • Путь к модулю node.js?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Если модуль находится в node_modules, то он будет нормально загружаться через имя: require('database'), а Вы скорее всего сделали не модуль, а отдельный файл, который можно загружать не через имя, а через путь, require('/path/database.js') или через require('./database.js') из текущей папки. В некоторых системах находит и require('database.js') или require('./database') или require('/path/database.js'), но лучше писать require('./database.js') или делать полноценный модули в node_midules, который будет иметь свой корневой файл, указанный в своем package.json в параметре "main" и тогда его можно будет загружать по имени из любого места кода (любого каталога и любого js файла в проекте).
    Ответ написан
    Комментировать
  • CDN и browserify?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Случайный отказ CDN - это паранойя, гораздо более вероятен случайный отказа node.js или nginx. Но если это так, то поставьте в html 1 строчку проверки, если JS собранный browserify в один файл не подгрузился и не установил определенный флаг, то мы просто рефрешаем страницу.
    Ответ написан
    3 комментария
  • Как заставить Node JS Выполнять код по порядку?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Оборачиваем в https://github.com/caolan/async
    async.series([
        function(){ /* выполнится первым */ },
        function(){ /* выполнится вторым */ }
    ]);
    Ответ написан
    1 комментарий
  • Всё таки, как работать с мультиязычностью?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Лучше все языковые версии хранить в одном месте, или все на диске или все в базе. Если уж нужно в двух и более местах, если эти шаблоны прямо уж так сильно меняются, то лучше базу принять за основное место и синхронизировать на диск при изменениях или по запросу. Вы же можете генерировать эти json файлы когда захотите. Как хранить в базе есть два варианта, или внутри одного документа/объекта много языковых версий или рядом, добавляя индексируемый ключ. Это зависит от того, какие данные и какие к ним типичные запросы приходят, если данных мало и запросы редкие, то разницы нет. Например, если там 10 форм и у каждой 5 языков, а формы меняются 1 раз в неделю, то удобнее хранить все языки в формах и при изменении перегенерировать JSON на диске. А если это user-generated контент, который нужно постоянно отдавать прямо из базы, то выносите идентификатор языка в ключ с индексом, так запросы будут быстрее. А при большой нагрузке лучше кешировать языковые версии прямо в оперативной памяти на сервере, чтобы быстрее отдавать и реже ходить к базе за ними.
    Ответ написан
    2 комментария
  • Как выполнить функцию после ajax-запроса типа post?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    UPD: поможет флаг в cookie или localstorage, например: localStorage.lastResult = "error";

    Рядом с complete в вызове $.ajax добавьте еще error: function() {} или error: functionName если она уже где-то была определена.
    Ответ написан
    3 комментария
  • Как починить: Error: EPERM, lstat 'e:\System Volume Information' at Error (native)?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    По той ссылке, что Вы дали и лежит решение, т.к. на венике могут встречаться файлы и каталоги с разными правами доступа, то нужно выделять из общего потока ошибок EPERM и игнорировать их. Полное игнорирование ошибок: finder.on('error', function (err) {}); Если глушить только EPERM то наверно так:
    finder.on('error', function (err) {
        if (err.code !== 'EPERM') finder.stop();
    });
    Ответ написан
    3 комментария
  • Javascript backend frameworks or vanilla js?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Посмотрите вот этот мой развернутый ответ: Подсоветуйте фреймворк для node?
    Инструментов можно набрать тут: nodeframework.com и тут https://github.com/sindresorhus/awesome-nodejs и тут https://github.com/vndmtrx/awesome-nodejs

    По БД рекомендую MongoDB, если у Вас данные аморфные, сложной или часто изменяющейся структуры с этими драйверами: https://www.npmjs.com/package/mongodb А если данные имеют редко меняющующуюся структуру и хорошо ложатся в таблицы, то берите реляционку, лучше PostgreSQL, с драйверами: https://www.npmjs.com/package/pg Но я не люблю и не рекомендую ORM, обычно от них больше проблем, тормозов и дополнительной работы больше, чем выгоды от их внедрения. Если уж приспичит, то для монги есть mongoose: mongoosejs.com это ODM, аналог ORM для документных баз, а для PG есть много вариантов, которые основаны на том же драйвере pg.

    Паттерн MVC он вообще изначально был изобретен для графических интерфейсов пользователя, и там он еще как-то себя оправдывает, да и то кривенько, почитайте эти мои статьи: habrahabr.ru/post/204958 и habrahabr.ru/post/117791 Для ноды это вообще противоестественно. GUI и бекенд должны быть разделены сетевым API, на которое вешаются что мобильные приложения, что браузерные, что оконные, это уже без разницы.
    Ответ написан
    Комментировать
  • Как определить, что на конкретной странице находится какой-то залогиненый пользователь?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Нужно определить, что пользователь не просто зашел, а сидит на этой странице, не закрыл ее и не выключил комп. Для этого нужно открыть websocket на сервер и периодически (5-10 секунд) по нему присылать кусочек данных (heartbeat). А на сервере нужно держать таблицу соответствий, кто "держит" какую страницу. Берите библиотеку https://www.npmjs.com/package/websocket и реализовывайте.
    Ответ написан
    Комментировать
  • Какие плюсы и минусы двух комбинаций технологий разработки?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Ради Аллаха, выбросите Вы все эту ерунду, возьмите React для клиента + один из фреймворков для создания серверного API на ноде. Шаблонизировать на сервере это очень специфическая задача, нужная разве что для публикации контента. А приложения лучше писать как SPA (одностраничное приложение, т.е. клиент грузится в браузер и все дальнейшие обмены данными JSON формате через API).
    Ответ написан
    6 комментариев
  • Почему при попытке подключиться к mysql под node.js приложение уходит в ошибку?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Скорее всего поможет первый вариант:
    1. Перенесите connection.connect(); в сразу после определения var connection
    2. Попробуйте заменить 127.0.0.1 на localhost
    3. Проверьте порт 3306, его можно явно задать в createConnection
    Ответ написан
    Комментировать
  • В каких случаях лучше использовать Apache, а в каких Express?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Сравнение не совсем корректное. Если Вы пишете серверную сторону на JavaScript под Node.js, то используете встроенный http сервер (express это надстройка над встроенным сервером, мало имеющая отнощения к веб-серверу вообще), а если пишете на PHP или другом языке, работающим через CGI с Apache, то используете Apache.
    Ответ написан
    3 комментария
  • Как лучше сделать чат?

    MarcusAurelius
    @MarcusAurelius Куратор тега Node.js
    автор Impress Application Server для Node.js
    Я не вижу ни малейшего смысла в socket.io, если уровень поддержки websocket в браузерах цже давно достаточный: caniuse.com/#feat=websockets и API вебсокетов вполне простое и понятное. А для ноды берите серверную библиотеку https://www.npmjs.com/package/websocket
    Ответ написан
    Комментировать