Node.js Socket IO:如何将套接字数据连续保存到MongoDB

时间:2016-08-03 19:28:20

标签: javascript angularjs node.js mongodb socket.io

我正在使用THREE.js在浏览器中构建3D游戏。很有趣,但我遇到了以下情况:

我的3D场景中的对象在用户输入的驱动下不断移动。我需要实时将对象的位置保存到我的数据库中。

让我们从前端开始吧。 Angular.js正在使用其内置的$watch功能观看我的对象的位置。对象的位置可以每秒多次更改

在每次更改时,我使用Node.js向后端Socket IO服务器发出一个事件,如下所示:

socket.emit('update', { 
    id: id,
    position: position
});

后端中,事件被捕获并立即发送给同一Socket IO Room中的其他成员。这样,这个房间里的每个人都可以获得最实时的更新。

现在,因为事件可以每秒多次发生,所以我不想在每次更改时更新我的​​MongoDB集合,因为这会导致很多开销。相反,我正在寻找偶然将数据保存到数据库的方法。

我通过使用Node.js setInterval函数找到了解决方案,该函数每隔1000ms保存一次数据。对于在后端接收的每个不同的id(每个对象都是唯一的),在JavaScript对象上创建一个新密钥,从而跟踪每个对象的变化。

后端的(简化)代码:

let update_queue = new Object();

// ...

// Update Event
socket.on('update', (msg) => {

    // Flag Changes
    if (!update_queue[msg.id]) update_queue[msg.id] = { changes: true };

    // Set Interval Timer
    if (!update_queue[msg.id].timer) {

        update_queue[msg.id].timer = setInterval(() => {

            if (!update_queue[msg.id].changes) {
                clearInterval(update_queue[msg.id].timer);
                return;
            }

            // This saves data to MongoDB
            Object3DCollection.update(msg.id, msg.position)
                .then((res) => {
                    console.log('saved');
                });

            // Unflag Changes
            update_queue[msg.id].changes = false;

        }, 1000);
    }

    // Immediate Broadcast to Socket Room
    socket.broadcast.to('some_room').emit('object_updated', msg);
});

问题

这是处理非常频繁的套接字数据并将其保存到数据库的正确方法吗?或者是否有其他更强烈或更好的建议/解决方案。

注意

我不想等待我的对象保存到数据库中,然后将保存的数据发送到套接字室的其余部分。数据库写操作的延迟不适合我正在处理的实时游戏情况。

提前致谢!所有建议/解决方案均受到赞赏并将予以考虑。

0 个答案:

没有答案