These are chat archives for NodejsRUS/chat

5th
Apr 2016
Pavel
@1Pauletto
Apr 05 2016 07:03

Ребята подскажите пожалуйста есть ли принципиальная разница между
var redisClient = redis.createClient(/конфиг/);;
io.on('connection', function(socket) {
redisClient.on('notification', ....);
});

И

io.on('connection', function(socket) {
var redisClient = redis.createClient(/конфиг/);;
redisClient.on('notification', ....);
});

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

Vadim Petrov
@imposibrus
Apr 05 2016 07:06
@1Pauletto правильно понимаешь
Pavel
@1Pauletto
Apr 05 2016 07:07
@imposibrus а будет ли течь память в первом случае?
Vadim Petrov
@imposibrus
Apr 05 2016 07:08
@1Pauletto скорее вы превысите лимит listener'ов.
Pavel
@1Pauletto
Apr 05 2016 07:16
listner'ов же может быть сколько память позволяет, верно? Можно как-то облагородить код с помощью промисов?
Vadim Petrov
@imposibrus
Apr 05 2016 07:33

@1Pauletto по-умолчанию - 10.
https://nodejs.org/api/events.html#events_eventemitter_defaultmaxlisteners

Вообще, лучше вынести

redisClient.on('notification', ....);

из connection.
вам нужно отправлять всем клиентам одно и тоже событие, когда приходит notification от Редиса или каждому клиенту свое кастомизированное или вообще отправлять событие только части клиентов?

Pavel
@1Pauletto
Apr 05 2016 07:34
вот мне товарищ в вк группе тоже рекомендует вынести, но я не могу понять как я сокету передам это сообщение, если у меня сокет в анонимной функции
Есть магаз, на него заходит клиент, мы знаем id клиента . При открытие страницы мы коннектим его к нашему серверу сокетов и джоиним в комнату по его id. Далее база/редис плюет нам сообщения, в сообщении указана комната в которой его надо транслировать. Если сокета комната совпадает с комнатой сообщения, то мы ему посылаем это сообщение
у меня собственно все это дело работает, я просто чувствую что 100% можно улучить это спагетти из колбеков)
Vadim Petrov
@imposibrus
Apr 05 2016 07:37

вот пример функции поиска всех активных сокетов в группе:

import socketIo from 'socket.io';

const io = socketIo(/*...*/);

var findClientsSocket = (roomId, namespace) => {
  var res = [],
      ns = io.of(namespace || '/');

  if (ns) {
    for (let id in ns.connected) {
      if(ns.connected.hasOwnProperty(id)) {
        if(roomId) {
          let rooms = Array.isArray(ns.connected[id].rooms) ? ns.connected[id].rooms : [],
              index = rooms.indexOf(roomId);

          if(index !== -1) {
            res.push(ns.connected[id]);
          }
        } else {
          res.push(ns.connected[id]);
        }
      }
    }
  }
  return res;
};

можете по аналогии написать функцию поиска сокета по id.

Pavel
@1Pauletto
Apr 05 2016 08:02
@imposibrus благодарю, сейчас попробую
@imposibrus подскажите почему лучше вынести в данном случае событие получения нотификации редисом из коннекшена сокета?
Vadim Petrov
@imposibrus
Apr 05 2016 08:11
@1Pauletto на каждого подключившегося клиента будет создаваться по одному listener'у. смысла в этом не много. проще (быстрее) иметь один listener, который сам найдет все сокеты и пнет их.
Pavel
@1Pauletto
Apr 05 2016 08:37
@imposibrus а в чем смысл проверять есть ли такой ключ в ns.connected если мы только что его взяли?
Vadim Petrov
@imposibrus
Apr 05 2016 08:43
@1Pauletto вы про .hasOwnProperty?
Pavel
@1Pauletto
Apr 05 2016 08:43
@imposibrus да, именно
Vadim Petrov
@imposibrus
Apr 05 2016 08:46
@1Pauletto чтобы избежать ситуации в будущем, когда случайно свойство id может переехать в прототип (считай там будет уже другое значение). если честно, я пишу эту строчку только потому, что IDE меня пинает)
подробнее:
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
Pavel
@1Pauletto
Apr 05 2016 08:49
@imposibrus имеется ввиду если библиотеку перепишут? там же тогда код в принципе сломается и нужно будет переписывать, функция не будет работать. И в этом случае есть вариант что вы никогда не узнаете об ошибке, ибо там будет всегда отдаваться пустой массив.
Vadim Petrov
@imposibrus
Apr 05 2016 08:56
@1Pauletto да, чет я поторопился (не проснулся еще).
имеется ввиду, что ns.connected - это объект, ключами которого являются id сокетов.
for..in возьмет также и унаследованные свойства, мне они не нужны. поэтому и стоит проверка на только собственные свойства.
Pavel
@1Pauletto
Apr 05 2016 08:59
вот я распечатал ns.connected
[ '/#pqt2P0Wwlgx-op4jAAAA',
'/#NmWkBy7Ds0EMPSFTAAAB',
'/#iZGqLORSdiTO4j6CAAAC' ]
это ключи этого объекта
мы по ним бежим, они же 100% есть в ns.connected
или Object.keys просто не берет унаследованные свойства?
Vadim Petrov
@imposibrus
Apr 05 2016 09:02
@1Pauletto вы распечатали собственные свойства) никто не мешает разработчикам добавить что-то в прототип.
мы к чему все это обсуждаем? если не хотите лишний if в коде - никто не заставляет.
Pavel
@1Pauletto
Apr 05 2016 09:02
@imposibrus я пытаюсь понять как правильно и почему, а не просто ctrl+c и ctrl+v сделать:)
я в нескольких сообществах задавал этот вопрос, поэтому когда лишь в 1 из всех мне ответили я решил не упускать свой шанс и докопаться до правды:)
Vadim Petrov
@imposibrus
Apr 05 2016 09:04
@1Pauletto аа, это хорошо)
вот на 5 минут статейка с объяснениями и примерами (вам последний пример нужен):
http://javascript.ru/for..in
Pavel
@1Pauletto
Apr 05 2016 09:06
@imposibrus спасибо, стало намного понятнее
Pavel
@1Pauletto
Apr 05 2016 09:16
@imposibrus еще интересно почему у вас проверка идет на массив, я распечатал typeof ns.connected[id].rooms - это объект, в вашем примере indexOf будет всегда -1, заменил для себя на
var rooms = ns.connected[id].rooms ? ns.connected[id].rooms : {},
                    isExist = rooms.hasOwnProperty(roomId);

                if (isExist) {
                    res.push(ns.connected[id]);
                }
Vadim Petrov
@imposibrus
Apr 05 2016 09:19
@1Pauletto хм, может разница в версиях (у меня этот код использовался в socket.io@1.3.7)...
он работал всегда хорошо)
Pavel
@1Pauletto
Apr 05 2016 09:25
@imposibrus спасибо большое, в итоге все работает:)