如何用Bacon.js实现Node.js消息应用的用户连续消息检测(防垃圾消息)
嘿,我来帮你搞定这个群聊连续消息检测的逻辑!看起来你已经选对了Bacon.js的slidingWindow操作符,接下来只需要补全过滤逻辑就行,我给你整理了完整的可运行代码,还有详细的解释:
完整实现代码
const Bacon = require('baconjs'); const bus = new Bacon.Bus(); const CONSECUTIVE_MESSAGES = 5; bus.slidingWindow(CONSECUTIVE_MESSAGES) // 先过滤掉消息数量不足N的窗口,避免初始阶段的误判 .filter(messages => messages.length === CONSECUTIVE_MESSAGES) .filter(messages => { // 取窗口第一条消息的用户ID作为基准 const targetUserId = messages[0].user.id; // 检查窗口内所有消息是否都来自同一个用户 return messages.every(msg => msg.user.id === targetUserId); }) .onValue(messages => { // 这里写检测到违规后的处理逻辑,比如告警、限制发送 const user = messages[0].user; console.log(`⚠️ 检测到用户 ${user.name}(ID: ${user.id}) 连续发送了 ${CONSECUTIVE_MESSAGES} 条消息!`); }); // 👇 可以用下面的测试用例验证逻辑 // 测试1:用户Pep连续发5条,会触发检测 for (let i = 0; i < CONSECUTIVE_MESSAGES; i++) { bus.push({ text: `消息${i+1}`, user: { id: 1, name: "Pep" } }); } // 测试2:混合不同用户的消息,不会触发检测 bus.push({ text: "我是Alice", user: { id: 2, name: "Alice" } }); bus.push({ text: "Pep又发消息了", user: { id: 1, name: "Pep" } });
关键逻辑解释
- 第一个
filter:因为slidingWindow在消息数量还没达到CONSECUTIVE_MESSAGES时,会返回长度从1到N-1的数组,这时候我们不需要检测,所以先把这些短窗口过滤掉。 - 第二个
filter:先拿窗口里第一条消息的用户ID当基准,然后用every方法检查窗口内所有消息的用户ID都和基准一致——这样就能确保这N条消息是同一个用户连续发送的。 onValue:这里是检测到违规后的处理环节,你可以根据需求改成发送系统提示、暂时限制该用户发送权限,或者记录到监控系统里。
额外提醒
如果你的需求是用户在一段时间内发送N条消息(不是严格连续),那可能需要换成bufferWithTime或者bufferWithCount结合时间的操作符,但根据你描述的“防范垃圾消息发送者”,当前的严格连续检测应该更适用。
内容的提问来源于stack exchange,提问作者Guido
相关产品推荐
相关产品推荐

