2016-08-01 58 views
0

我正在设计一个在线游戏。在游戏中,玩家会进行一系列动作。先前的移动可以影响后续移动的移动。这意味着移动顺序至关重要。这些举动被实现为AJAX请求。我的后端是带节点的expressjs。如何以不能被篡改的方式确定http请求的顺序?

我可以以异步方式实现移动,但有轻微的机会,前面的举动很可能后来经过移动完成。我可以确保移动任务按照通过将请求链接到承诺而收到请求的顺序完成,但是我可以保证在另一个之前发出的http请求会在另一个之前到达吗?

我能时间戳移动客户端,并依次处理它们。我担心的是用户可能会通过模拟时间戳请求来欺骗,破坏订单,如果游戏即将失败,就会崩溃。这是因为如果以错误的顺序执行某些动作将会破坏游戏。

当然我可以处理这个错误,但我无法通过检查它们的内容来找出移动的真实顺序,因为有时多个命令会合法,但玩家可能有更多的信息,因为做出某些动作是至关重要的。真正的订单被执行。即使游戏实际上不会崩溃,也不可能确定真实的顺序。即使我在每个请求中包含整个游戏状态,它仍然可能是可欺骗的。

有一些方法我能确定的方式,用户不能乱动http请求的顺序?我看不到这个问题的另一个解决方案。

+0

如果我需要那么我的选择是websocket。 Websocket更安全(不完全如http://blog.ironwasp.org/2014/11/analysing-testing-and-fuzzing-websocket.html)。客户端请求的顺序由服务器'.on('data''定义,所有的请求必须通过客户端+服务器的时间戳存储到数组中。服务器必须按时间戳执行请求数组。 –

+0

是的,我同意..你可以检查我的游戏github ..link是在我的生物...我做了简单的游戏与画布和socket.io –

+0

如果你与承诺连锁,然后第二个Ajax请求不发送,直到第一次完成,所以这是一个秩序的总保证 – jfriend00

回答

0

这真的不清楚你要解决什么问题。为客户端编写一堆http请求,然后按发送顺序处理它们(不管接收到响应的顺序如何),这非常简单。如果您同时发送多个请求,那么任何承诺驱动的ajax调用(如jQuery)和Promise.all()的简单组合都可以为您做到这一点。

如果你没有在同一时间发送它们,这样就可以发送一个请求,稍后发送另一个请求(但之前之前的响应是回),然后发送一些请求,等等,然后你可以创建一个响应队列。每个Ajax调用都绑定到一个队列条目。当响应返回时,响应进入队列条目。每次获得响应时,您都会处理队列中最早的响应的项目​​,并按队列顺序处理它们。这允许你做随机发送时间请求,但总是按顺序处理响应。由于所有这些顺序都是在客户端完成的,因此它不是防篡改(客户端没有任何防篡改功能),但它需要实际修改Javascript或队列数据结构,而不仅仅是修改响应为了改变处理的顺序。为了使事情更具防篡改性,您必须将更多决策权移交给服务器,以防止其被篡改。

这里有一个简单的基于承诺的Ajax队列,让你想发送尽可能多的请求,并保证了响应将按顺序进行处理。

var queueAjax = (function() { 
    var lastAjax = Promise.resolve(); 

    return function (url, options) { 
     // chain to the prior promise so this won't get resolved until all prior items 
     // in the queue have been fulfilled in some way 
     var priorPromise = lastAjax.catch(function() { 
      // always fulfilled 
      return; 
     }); 
     var ajaxPromise = doAjax(url, options).then(function(val) { 
      return {val: val}; 
     }, function(err) { 
      return {err: err}; 
     }); 
     lastAjax = Promise.all([ajaxPromise, priorPromise]).then(function(results) { 
      var result = results[0]; 
      // if there was an error, then throw to reject with that err 
      if (result.hasOwnProperty("err")) { 
       throw err; 
      } else { 
       return result.val; 
      } 
     }); 
     return lastAjax; 
    } 
})(); 

// sample usage 
queueAjax(someUrl, someOptions).then(function(val) { 
    // process results 
}); 

queueAjax(someUrl2, someOptions2).then(function(val) { 
    // process results 
}); 

queueAjax(someUrl3, someOptions3).then(function(val) { 
    // process results 
}); 

这个排队系统的功能将在平行Ajax请求,但确保他们.then()处理程序调用请求的发送顺序。与Promise.all()不同,您可以随时将新请求添加到队列中,并将它们添加到序列中。

这是一个工作演示:https://jsfiddle.net/jfriend00/7r2j1qme/

相关问题