在 MongoDB 中使用带有 Socket.io 的 Change Stream 时,“更改”被多次触发

Posted

技术标签:

【中文标题】在 MongoDB 中使用带有 Socket.io 的 Change Stream 时,“更改”被多次触发【英文标题】:While using Change Stream in MongoDB with Socket.io, the on 'change' is getting triggered multiple times 【发布时间】:2021-08-21 22:03:33 【问题描述】:

我一直在尝试在 mongodb 中捕获任何实时更新或插入,并使用 socket.io 在下一页上相应地更改信息。但是,只要数据库中有任何更新,“更改”流就会被多次触发。我认为这也可能是套接字动作缓慢且延迟的原因。非常感谢任何形式的帮助。

const Order = new mongoose.model("Order", orderSchema);

io.on('connection', function(socket)
    console.log(socket.id);
    Order.watch([ $match: operationType: $in: ['insert']]).
    on('change', data => 
        console.log('Insert action triggered'); //getting triggered thrice
        console.log(new Date(), data.fullDocument);
        socket.emit("changes", data.fullDocument); 

    );
    Order.watch([ $match: operationType: $in: ['update']]).
    on('change', data => 
        console.log('Update action triggered'); //getting triggered thrice
        console.log(new Date(), data.updateDescription.updatedFields);
        socket.emit("customer", data);
    );

);

【问题讨论】:

【参考方案1】:

您需要将您的 mongodb changeStreams 放在 io.on('connection') 之外并使用 io.emit() 而不是 socket.emit()

下面是代码示例:

const Order = new mongoose.model("Order", orderSchema);

io.on('connection', function(socket)
    console.log(socket.id);

    socket.on('disconnect', (reason) => 
        console.log(reason);
    );
);

Order.watch([ $match: operationType: $in: ['insert']]).
on('change', data => 
    console.log('Insert action triggered');
    console.log(new Date(), data.fullDocument);
    io.emit("changes", data.fullDocument); 

);
Order.watch([ $match: operationType: $in: ['update']]).
on('change', data => 
    console.log('Update action triggered');
    console.log(new Date(), data.updateDescription.updatedFields);
    io.emit("customer", data);
);

【讨论】:

【参考方案2】:

@swati sinha 答案对我有用,但我也想使用更改流和套接字在单独的函数中,所以这就是我做一些调整的原因

const Order = new mongoose.model("Order", orderSchema);

let OrderStream = Order.watch([ $match: operationType: $in: ['insert']])

io.on('connection', function(socket)
    console.log(socket.id);

    OrderStream.on('change',function(change)
        socket.emit('changes',change)
    )

    socket.on('disconnect', (reason) => 
        console.log(reason);
    );
);
 

【讨论】:

以上是关于在 MongoDB 中使用带有 Socket.io 的 Change Stream 时,“更改”被多次触发的主要内容,如果未能解决你的问题,请参考以下文章

使用 Socket.io 在 mongodb 中插入数据

使用socket.io连接mongodb

Socket.io - React:如何在 React 中检索保存的 socket.io 数据(MongoDB)?

socket.io 和按对象 id 过滤 mongodb

socket.io 和按对象 id 过滤 mongodb

MongoDB 更改流与 socket.io