所以这个问题困扰了我好一阵子了。基本上,我有硬币翻转游戏系统设置,其中一个用户创建了一个大厅供其他用户加入,当一个人加入时,他们掷硬币并获胜者获得了两个用户的积分。
如果一段时间内没有人加入并获得积分,则游说者可以取消游说。这就是问题所在。如果创建者请求两次或更多次取消大厅,而两次请求之间的时间间隔很短,则在第一个请求完全完成并更新数据库之前,由于大厅的状态仍然“可用”,因此也会执行任何其他取消请求”。一旦第一个请求完成并且数据库已更新(大厅状态设置为“已取消”),其他取消请求将失败。因此,如果成功,游说者可以将他的观点重新获得2次或更多次。
当2个用户同时加入一个大厅时,也会发生此问题,因为我的处理方式非常相似。
我该怎么做,以便第一个请求完全运行,并在其他请求得到处理之前等待数据库更新。
客户
$('#cancelLobby').click( () =>{
socket.emit('cancelLobby', lobby-id);
});
服务器
socket.on('cancelLobby', (id) => {
if(id){
Coinflip.findById({_id: id}).lean().exec( (err, res) => {
if (err) throw err;
if(res == null || res.status == "Completed" || res.status == "Canceled"){
socket.emit('serverMessage', {
type: 'error',
title: 'Error',
message: 'This lobby doesn\'t exist or has already ended'
});
return;
}
if(res.creator_name != socket.request.user.name){
socket.emit('serverMessage', {
type: 'error',
title: 'Error',
message: 'Error occured while canceling the lobby'
});
}else {
Coinflip.findOneAndUpdate({_id: id}, {$set: {status: 'Canceled'}}, (err) =>{
if (err) throw err;
socket.emit('serverMessage', {
type: 'success',
title: 'Success',
message: 'Lobby canceled successfully, you will get your points back shortly.'
});
});
}
})
}else{
socket.emit('serverMessage', {
type: 'error',
title: 'Error',
message: 'Error occured while canceling the lobby'
});
}
});
答案 0 :(得分:0)
您只能(在客户端和服务器上)处理一次事件:
$('#cancelLobby').one('click', () => {
socket.emit('cancelLobby', lobby-id);
});
或
socket.once('cancelLobby', (id) => {
...
});