socketio如何过滤事件(特别是flask-socketio)

时间:2019-01-07 14:38:45

标签: http optimization websocket socket.io flask-socketio

背景

假设有N个客户端和N个节点,每个节点都会发出一条包含统计信息及其名称的消息。单个客户端n∈N仅关心特定节点n∈N。

建议的解决方案

每个客户端都侦听特定的事件 node_name ,当服务器从带有 node_name 的节点接收消息时,发出事件 node_name

问题

发出事件 node_name

将消息发送给每个客户端n∈N,然后在没有特定 node_name

侦听器的情况下将其丢弃

OR

服务器是否保留元数据并知道哪些客户端/连接正在监听事件 node_name 并仅发送给特定的客户端n

修改

后者可以通过名称空间实现

OR

为每个节点创建一个房间是否明智?这些房间会用作元数据吗?

1 个答案:

答案 0 :(得分:0)

事件在客户端级别被过滤,而名称空间和房间在服务器级别

在相同名称空间和房间内的所有已连接客户端都将发送所有事件

在源代码中查看,我们发现flask_socketio在socketio之上提供了一层,它的merge(...eventObservables) .pipe(switchMap(({ syncWithServer }) => { const source = of(cloneDeep(this.getData())) .pipe(tap((data) => this.storageService.storeItem(data.id, { data: data, synced: false }))); if (syncWithServer) { return source.pipe(delay(5 * 1000), switchMap((data) => this.apiService.saveData(data) .pipe(tap(() => this.storageService.storeItem(data.RespondentId, { data: data, synced: true })), tap((response) => response && this.setData(response['Data'], false))))); } return source; })) 中包含一些包装函数,该函数从其核心文件的实例化属性调用函数。

__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

鉴于结构,最好使用 node_name 作为特定预定义命名空间下的房间名称。

相关问题