Kuzzle如何按条件仅向目标订阅用户派发doc_created事件
Kuzzle定向向指定用户派发文档创建事件的实现方案
方案一:订阅阶段绑定用户过滤规则 (优先推荐,性能最优)
这个方案是利用实时订阅原生的过滤能力,从根源上避免给非目标用户推送消息,没有额外拦截开销。
- 核心逻辑:用户发起
doc_created事件订阅时,不要传空的匹配过滤条件,而是增加和当前登录用户绑定的等值匹配规则,仅当文档的forUser字段值和当前用户名一致时,才接收对应事件通知。 - 安全加固:不要让前端自行传入过滤规则里的用户名参数,避免恶意用户篡改规则收到他人的消息。可以通过服务端插件拦截实时订阅请求,从认证后的请求上下文里自动取出当前登录用户名,注入到订阅过滤条件中,对客户端完全透明。
- 效果:用户A订阅时自动加上
forUser = "A"的匹配规则,用户B订阅时自动加上forUser = "B"的匹配规则,新建forUser = "A"的文档时,实时引擎只会匹配到A的订阅规则,天然不会给B推送消息,不需要额外拦截。
方案二:服务端实时派发管道拦截(适合存量业务改造)
如果现有客户端已经做了无差别订阅,改造成本高,可以通过服务端管道在消息派发前做校验拦截,不需要修改客户端代码。
- 核心逻辑:注册
realtime:dispatch管道事件处理器,这个事件会在每条实时通知准备发送给单个订阅用户前触发,你可以拿到待发送的通知内容、以及接收方的认证用户信息,做匹配校验:- 先过滤出你需要处理的文档创建类型通知,跳过其他类型的实时消息
- 从通知携带的文档内容中取出
forUser字段值 - 从请求上下文中取出当前接收消息的用户的认证用户名
- 如果两个值不匹配,直接抛出拦截错误终止这次派发,消息就不会发送给对应用户;匹配则正常放行
- 参考实现代码:
class TargetUserDispatchPlugin { init (config, context) { this.context = context; this.pipes = { 'realtime:dispatch': async (notification, request) => { // 仅处理文档创建类的事件通知 if (notification.type !== 'document' || notification.action !== 'create') { return notification; } const targetUsername = notification.result._source.forUser; // 从认证上下文取当前接收方的用户名,按你实际的用户存储字段调整 const receiverUsername = request.context.user.username; // 非目标用户直接拦截 if (targetUsername !== receiverUsername) { throw new context.errors.ForbiddenError('非目标用户,拦截消息'); } return notification; } }; } }
避坑提示
不要在文档写入后的事件里手动实现消息推送逻辑,相当于完全重写实时派发模块,会漏掉订阅房间匹配、连接状态同步、权限校验、断网重连消息补发等原生能力,后续维护成本极高。
内容的提问来源于stack exchange,提问作者Screwt-k
相关产品推荐
相关产品推荐

