Ответы пользователя по тегу Node.js
  • Как сделать авторизацию клиента "как у Habrahabr"?

    HoHsi
    @HoHsi Автор вопроса
    Под личные поиски:
    =======================
    *Данный метод называется SSO
    Ответ написан
    Комментировать
  • Как отправить запрос на nodejs?

    HoHsi
    @HoHsi
    Мне кажется, что все отвечающие переусложняют. А автору просто хотелось зайти на свой сайт.

    Если приложение слушает отличный от 80 порт, то зайти на него можно просто прописав :5000 после домена или IP, примерно так:

    http://127.0.0.1:5000/

    Или можно использовать Nginx, что-бы проксировать запросы с 80 порта на Node.
    Ответ написан
    Комментировать
  • На сколько хорошо использовать NodeBB?

    HoHsi
    @HoHsi
    NodeBB работает на Javascript, что соответственно не делает не какой нагрузки на сервер.

    Делает. Все что работает на сервере, даже grep, делает на него нагрузку. Тут вопрос в том какую нагрузку он делает. Та же нода будет независимо от кол-во пользователей есть 50mb RAM. Но в свою очередь за счет этого будет быстрее отвечать. Это позволит обслужить большее кол-во пользователей, но за счет постоянного проживания в RAM.

    Но я не совсем понимаю как это работает, прогуглил и понял что оно работает на MongoDB и не совсем понял, получается данные с сайта который мы сделаем на NodeBB, такие как имена и пароли пользователей, вопросы, ответы и т.д. хранятся полностью на серверах MongoDB ? И

    Аммм, ну да. Так работают все Web приложения. Они хранят почти все динамические данные в базах. И не важно, SQL это, или NoSQL.

    Если вы подразумеваете, что есть какие-то MongoDB сервера, как сервисы, то нет. Это просто база данных, как Postresql или MySQL. Вам прийдется ее так же поднимать на одной из своих машин, что автоматически значит, что вы храните все "у себя".

    Если же вы подразумеваете, что данные хранятся непосредственно в процессе NodeJS, это от части правильно, но все равно 90% данных будут лежать в базе, те же пользователи, вопросы и т.д.

    И по этому может хоть до миллионов запросов быть? Или как это работает?

    Нет. Вы все так же ограничены RAM, CPU, пропускной способностью, лимитом трафика. Все тоже самое, что и в других Web приложениях, на любых языках и платформах. Никакой магии.
    Ответ написан
    4 комментария
  • Какой фреймверк выбрать? Кто что юзает и почему?

    HoHsi
    @HoHsi
    В последнее время активно использую связку Express + exa.

    По сути дела первый - стандарт в Nodejs разработки (так или иначе ноги у многих фреймворков растут из него. Да и на текущий момент он самый популярный);

    А Exa избавляет Express от callback hell за счет ES7 async/await или ES6 генераторов. При этом как я понял он не лезет в сам Express и не меняет его, а просто примешивает асинхронные методы для роутеров.

    И получается что-то типо того:
    'use strict';
    const exa      = require('exa');
    const express  = require('express');
    
    const mongoose = require('mongoose');
    
    const app = exa(express()); // Примешивание методов
    
    const User = mongoose.model('User');
     
    app.$get("/", function * (req, res) {
      const users = yield User.find({}).exec();
     
      res.send(users);
    });
     
    app.use(function (err, req, res, next) {
      // Все ошибки свалятся сюда
     
      res.statusStatus(500);
    });
    Ответ написан
    Комментировать
  • Как подружить 1С Битрикс и Node JS?

    HoHsi
    @HoHsi
    Как уже предложил Алексей Уколов , можно использовать общую BD. Вполне рабочий, но небезопасный вариант.
    Я бы поискал какую-то прослойку, вроде самописного REST API до базы 1C (да, по сути она так же будет лезть руками в их базу, но все же, меньше вероятность что-то сломать, да и API уже обкатан).
    Ответ написан
    1 комментарий
  • Источники для изучения Node.js?

    HoHsi
    @HoHsi
    и скринкастов записано на версии 0.10 и ниже

    В Node со времен этой версии ничего критического не поменялось (я про API). Так, что смело смотрите этот скринкаст.

    А после уже можете подучить ES6-ES7, если хотите быть на острее.
    Ответ написан
    Комментировать
  • Как подменить результат вызова стандартного node.js модуля в тестах?

    HoHsi
    @HoHsi
    const child_process = {};
    child_process.exec = function () {
      // Все что угодно
    }


    Если CP используется не в тесте, а в самой либе, тогда можно как-нибудь извратиться с передачей child_process как параметра, тогда можно будет подсовывать любые функции вместо нее.
    Ответ написан
  • Как вернуть из асинхронных функции результат?

    HoHsi
    @HoHsi
    Во первых вы вызываете асинхронную версию exec, есть ее синхронный собрат: execsync

    Во вторых, тут не обойдется без промисов / коллеков / Async/Await.
    В текущей сборке, я бы рекомендовал использовать промисы, но сам я уже перешел на Async/Await c бабелем.
    function enabledApi(conf) {
      const config = {
        host:     conf.host,
        username: conf.us,
        password: conf.pa
      };
    
      return new Promise((resolve, reject) => {
        exec(config, '/ip service set api disabled=no', (error, response) => {
          const res = error ? 'error' : 'ok';
          console.log(`res is ${res}`);
    
          if (error) {
            reject(error);
          } else {
            resolve(response);
          }
        });
      });
    }
    
    const config = {
      host:'1.1.1.1',
      us:'user',
      pa:'123'
    };
    
    enabledApi(config)
    .then((res) => {
      console.log(`ress again is ${res}`);
    })
    .catch((err) => {
      console.error(`OMG! ${err.toString()}`);
    });


    Или все же с Async, но вам понадобится babel
    function enabledApi(conf) {
      const config = {
        host:     conf.host,
        username: conf.us,
        password: conf.pa
      };
    
      return new Promise((resolve, reject) => {
        exec(config, '/ip service set api disabled=no', (error, response) => {
          const res = error ? 'error' : 'ok';
          console.log(`res is ${res}`);
    
          if (error) {
            reject(error);
          } else {
            resolve(response);
          }
        });
      });
    }
    
    (async () => {
      const config = {
        host:'1.1.1.1',
        us:'user',
        pa:'123'
      };
    
      const res = await enabledApi(config);
    
      console.log(res);
    })()
    .catch((err) => {
      console.error(`OMG! ${err.toString()}`);
    });
    Ответ написан
    Комментировать
  • Почему не видно значения переменной?

    HoHsi
    @HoHsi
    Это называется IIFE. Так как запрос к базе - асинхонный, а for - синхонный, он отрабатывает быстрее, сохраняя внутренее значение i на финальной итерации. Это значит, что вам нужно замкнуть для каждого вызова i, что-бы он стал локальным. Это проблема var переменны, так как имеют область видимости всей функции, а не блока. Это можно решить:
    1 вариант - по старинке:
    for (var i=0, len = vendors.length; i < len ; i++) {
        (function (i) {
            console.log(i);
            connection.query('SELECT * FROM `brends` WHERE `brend_parrent`="'+vendors[і].id_folders+'";', function(err, rows, fields) {
                if (err) throw err;
                console.log(i);
            });
        })(i);
    }


    2 - с использованием ES6 let:
    for (let i=0, len = vendors.length; i < len ; i++) {
        console.log(i);
        connection.query('SELECT * FROM `brends` WHERE `brend_parrent`="'+vendors[і].id_folders+'";', function(err, rows, fields) {
            if (err) throw err;
            console.log(i);
       });
    }
    Ответ написан
    Комментировать
  • Как преобразовать массив полученный от mysql в другой вид?

    HoHsi
    @HoHsi
    connection.query('SELECT user FROM users', function(err, rows, fields) {
      if (err) { throw err; };
      
      const users = rows.map((row) => ""+row.user);
      callback(`Текст: ${JSON.stringify(users)}`);
    });
    Ответ написан
    Комментировать
  • Как прикрутить LiqPay к node.js?

    HoHsi
    @HoHsi
    Вот товарищ, что-то реализовывал https://github.com/smituk/liqpay. Может это уже конечный продукт, а может придется форкнуть и допилить
    Ответ написан
    Комментировать
  • Лучший способ реализации мультиязычности на Node.js?

    HoHsi
    @HoHsi
    Ответ написан
    Комментировать
  • Получить сессию из другого приложения?

    HoHsi
    @HoHsi
    Нужно использовать хранилище отличное от RAM. Это может быть MongoDB, Radis или любая другая NoSQL БД.
    Если вы используете "родной" модуль для сессий эспресса, то посмотрите тут: connect-mongo
    Ответ написан
    Комментировать
  • Время rps зависит от ядер машинки?

    HoHsi
    @HoHsi
    Зачем вам такие ухищрения? Поставьте load-balancer Nginx и несколько беков ноды. Так и скалировать легче, и должно выйти дешевле.
    Ответ написан
  • Как проверить информацию о пользователе вошедшем на страницу?

    HoHsi
    @HoHsi
    1) Перед рассылкой сохраняете в BD id пользователя. И генерируете UUID (или что-угодно уникальное).
    2) Формируете письмо с ссылкой вида www.site.ru/sale/< uuid >
    3) Когда пользователь переходит по этой ссылке, заставляем его авторизоваться (в случае если у вас приложение, установить его).
    4) Получив от ВК ID пользователя, делаем запрос к #isMember
    5) Если такой пользователь есть в базе, то меняем ему статус (в базе, на `received` или что-угодно), а UUID ключу ставим статус `activated` (что-бы эту ссылку не шарили).
    6) Отравляем/показываем скидку/ключ на почту/ВК/на странице
    Ответ написан
    9 комментариев
  • Какую Node.js библиотеку для промисов использовать?

    HoHsi
    @HoHsi Автор вопроса
    Написал тест на производительность.

    # Requires
    Benchmark   = require 'benchmark'
    lagoon      = require 'lagoonjs'
    
    async       = require 'async'
    Q           = require 'q'
    bluebird    = require 'bluebird'
    RSVP        = require 'rsvp'
    whenpromise = require 'when'
    # mpromise    = require 'mpromise' # Не соответствует стандарту
    es6         = require 'es6-promise'
    kew         = require 'kew'
    
    # Init
    logger      = new lagoon.Lagoon()
    
    # Functions
    fakeDelay = (name)-> (delay = 3)-> (callback)=>
        # console.log "[#{ name }] +"
        setTimeout =>
            callback()
        , delay
    
    fakeDelayPromiseQ = (delay)->
        deferred = Q.defer()
    
        fakeDelay("q")(delay) =>
            deferred.resolve()
    
        return deferred.promise
    
    fakeDelayPromiseBB = (delay)->
        new bluebird (resolve, reject)->
            fakeDelay("Bluebird")(delay) =>
                resolve()
    
    fakeDelayPromiseRSVP = (delay)->
        new RSVP.Promise (resolve, reject)->
            fakeDelay("RSVP")(delay) =>
                resolve()
    
    fakeDelayPromiseWhen = (delay)->
        deferred = whenpromise.defer()
    
        fakeDelay("When")(delay) =>
            deferred.resolve()
    
        return deferred.promise
    
    # fakeDelayPromiseM = (delay)->
    #     new mpromise (resolve, reject)->
    #         fakeDelay("M")(delay) =>
    #             resolve()
    
    fakeDelayPromiseES6 = (delay)->
        new es6.Promise (resolve, reject)->
            fakeDelay("ES6")(delay) =>
                resolve()
    
    fakeDelayPromiseKew = (delay)->
        deferred = kew.defer()
    
        fakeDelay("Kew")(delay) =>
            deferred.resolve()
    
        return deferred.promise
    
    # Time
    BenchmarkAsync = (delay, times = 3)-> new Benchmark "Async#parallel X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelay("Async")(delay)
    
            async.parallel queue, =>
                deferred.resolve()
    }
    
    BenchmarkQ = (delay, times = 3)-> new Benchmark "Q#all X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseQ(delay)
    
            Q.all(queue).then =>
                deferred.resolve()
    }
    
    BenchmarkBluebird = (delay, times = 3)-> new Benchmark "Bluebird#all X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseBB(delay)
    
            bluebird.all(queue).then =>
                deferred.resolve()
    }
    
    BenchmarkRSVP = (delay, times = 3)-> new Benchmark "RSVP#all X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseRSVP(delay)
    
            RSVP.all(queue).then =>
                deferred.resolve()
    }
    
    BenchmarkWhen = (delay, times = 3)-> new Benchmark "When#all X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseWhen(delay)
    
            whenpromise.all(queue).then =>
                deferred.resolve()
    }
    
    # BenchmarkM = (delay, times = 3)-> new Benchmark "M#all X #{ times } [#{ delay }ms]", {
    #     defer: true
    #     fn: (deferred)->
    #         queue = []
    #         for [0...times]
    #             queue.push fakeDelayPromiseM(delay)
    
    #         mpromise.all(queue).then =>
    #             deferred.resolve()
    # }
    
    BenchmarkES6 = (delay, times = 3)-> new Benchmark "ES6#all X #{ times } [#{ delay }ms]", {
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseES6(delay)
    
            es6.Promise.all(queue).then =>
                deferred.resolve()
    }
    
    BenchmarkKew = (delay, times = 3)-> new Benchmark "Kew#all X #{ times } [#{ delay }ms]", { 
        defer: true
        fn: (deferred)->
            queue = []
            for [0...times]
                queue.push fakeDelayPromiseKew(delay)
    
            kew.all(queue).then =>
                deferred.resolve()
    }
    
    results = {}
    async.eachLimit [1, 3, 100, 300, 1000, 5000, 10000, 50000, 100000, 1000000], 1, (times, cbt)->
        async.eachLimit [1, 5, 300, 1000], 1, (delay, cbd)->
            suite = new Benchmark.Suite
    
            suite.add BenchmarkAsync( delay, times )
                 .add BenchmarkQ( delay, times )
                 .add BenchmarkBluebird( delay, times )
                 .add BenchmarkRSVP( delay, times )
                 .add BenchmarkWhen( delay, times )
                 .add BenchmarkES6( delay, times )
                 .add BenchmarkKew( delay, times )
                 .on 'cycle', (event)->
                     logger.info String(event.target)
                 .on 'complete', ->
                     logger.warn "Fastest is #{ @.filter('fastest').pluck('name') }"
                     results[ times ] ?= {}
                     results[ times ][ delay ] = @.filter('fastest').pluck('name')
    
                     cbd()
                 .run { 
                     'initCount': 100
                     'async': false
                     'defer': true
                 }
        , ->
            cbt()
    , ->
        logger.log ''
        logger.log ''
        logger.log ''
        for times, resultd of results
            logger.log ''
            for delay, result of resultd
                logger.warn "Fastest is #{ result }"
    Ответ написан
  • Возможно ли асинхронно делать действия с элементами массива?

    HoHsi
    @HoHsi
    1) AMQP, и делегирование задач.
    2) Запускать дочерние процессы, разбивать массив на чанки и раздавать их сопрограммам.

    Первый способ:
    Преимущества:
    * Неограничен ни чем. Запускаете `воркеров X кол-во ядер`. Докупаете еще машину, ставите на ней ту же программу. И т.д.
    * Даже если процесс упал, часть массива не потеряется, а передастся другому воркеру.

    Недостатки:
    * Нужно время на совершение транзакции (надуманный недостаток, так как транзакция проходим за пару миллисекунд).

    Второй способ:
    Преимущества:
    * Моментальные транзакции (ну или как ответит родительский процесс).

    Недостатки:
    * Ограничен кол-во CPU.
    * Не расшияем
    Ответ написан
    Комментировать