Как socketio фильтрует события (особенно колба-socketio) - PullRequest
0 голосов
/ 07 января 2019

Фон

Предположим, что есть N клиентов и N узлов, каждый узел отправляет сообщение, которое содержит статистику и его имя. Один клиент n ∈ N заботится только о конкретном узле n ∈ N.

Предлагаемое решение

Каждый клиент прослушивает определенное событие имя_узла , когда сервер получает сообщение от узла со своим именем_узла , отправляет событие имя_узла

Вопрос

Когда генерируется событие имя_узла ,

будет ли сообщение отправлено каждому клиенту n ∈ N, а затем будет отброшено, если для этого конкретного пользователя нет прослушивателя имя_узла

OR

хранит ли сервер метаданные и знает, какие клиенты / соединения прослушивают событие имя_узла и отправляют только определенному клиенту n

Изменения

Может ли последнее быть достигнуто через пространства имен

OR

Желательно ли создать комнату для каждого узла? Будут ли эти комнаты действовать как метаданные

1 Ответ

0 голосов
/ 07 января 2019

События фильтруются на уровне клиента, а пространство имен и комнаты находятся на уровне сервера

Всем подключенным клиентам в одном пространстве имен и комнаты отправляются все события

Посмотрев в исходный код, мы видим, что flask_socketio предоставляет слой поверх socketio, который содержит некоторые функции-оболочки в __init__.py, который вызывает функции из экземпляров свойств своих основных файлов.

Функция emit из base_manager.py как таковая

    def emit(self, event, data, namespace, room=None, skip_sid=None,
         callback=None, **kwargs):
    """Emit a message to a single client, a room, or all the clients
    connected to the namespace."""
    if namespace not in self.rooms or room not in self.rooms[namespace]:
        return
    for sid in self.get_participants(namespace, room):
        if sid != skip_sid:
            if callback is not None:
                id = self._generate_ack_id(sid, namespace, callback)
            else:
                id = None
            self.server._emit_internal(sid, event, data, namespace, id)

Используется функция с именем get_participants, которая выглядит так

def get_participants(self, namespace, room):
    """Return an iterable with the active participants in a room."""
    for sid, active in six.iteritems(self.rooms[namespace][room].copy()):
        yield sid

Наконец, взгляд на функцию enter_room раскрывает структуру объекта, в котором хранится клиентская иерархия

def enter_room(self, sid, namespace, room):
    """Add a client to a room."""
    if namespace not in self.rooms:
        self.rooms[namespace] = {}
    if room not in self.rooms[namespace]:
        self.rooms[namespace][room] = {}
    self.rooms[namespace][room][sid] = True

Учитывая структуру, было бы лучше использовать имя_узла в качестве имени комнаты в определенном предварительно определенном пространстве имен.

...