背景
假设有N个客户端和N个节点,每个节点都会发出一条包含统计信息及其名称的消息。单个客户端n∈N仅关心特定节点n∈N。
建议的解决方案
每个客户端都侦听特定的事件 node_name ,当服务器从带有 node_name 的节点接收消息时,发出事件 node_name
问题
发出事件 node_name ,
将消息发送给每个客户端n∈N,然后在没有特定 node_name
侦听器的情况下将其丢弃OR
服务器是否保留元数据并知道哪些客户端/连接正在监听事件 node_name 并仅发送给特定的客户端n
修改
后者可以通过名称空间实现
OR
为每个节点创建一个房间是否明智?这些房间会用作元数据吗?
答案 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 作为特定预定义命名空间下的房间名称。