我正在使用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);
});
问题
这是处理非常频繁的套接字数据并将其保存到数据库的正确方法吗?或者是否有其他更强烈或更好的建议/解决方案。
注意
我不想等待我的对象保存到数据库中,然后将保存的数据发送到套接字室的其余部分。数据库写操作的延迟不适合我正在处理的实时游戏情况。
提前致谢!所有建议/解决方案均受到赞赏并将予以考虑。