如何以无法篡改的方式确定http请求的顺序?

时间:2016-08-01 21:02:54

标签: ajax node.js http express promise

我正在设计一款在线游戏。在游戏中,玩家进行一系列动作。以前的动作可以影响动作可以影响后期动作。这意味着移动顺序至关重要。这些动作是作为AJAX请求实现的。我的后端是节点表达。

我可以异步地实现移动,但稍后移动之前可能会完成早期移动的可能性很小。我可以通过将请求链接到promises来确保移动任务按照接收请求的顺序完成,但是我可以保证在另一个之前发出的http请求会在另一个之前到达吗?

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

当然我可以处理这个错误,但是我无法通过检查其内容来弄清楚移动的真实顺序,因为有时候多个订单是合法的,但玩家可能会获得更多信息,因为这一点非常重要执行真正的订单。即使游戏实际上不会崩溃,也无法确定真正的顺序。即使我在每个请求中包含整个游戏状态,它仍然可能是可欺骗的。

有什么方法可以用户可以篡改的方式确定http请求的顺序吗?我无法看到解决此问题的另一种方法。

1 个答案:

答案 0 :(得分:0)

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

如果您不是同时发送它们,以便您可以发送请求,稍后发送另一个请求(但在之前的响应恢复之前),然后发送更多请求等等,然后您可以只为响应创建一个队列。每个Ajax调用都与一个队列条目相关联。当响应返回时,响应进入队列条目。每次获得响应时,都会处理队列中您有响应的最旧项目,然后按队列的顺序处理它们。这允许您执行随机发送时间请求,但始终按顺序处理响应。

由于所有这些排序都是在客户端完成的,因此它不是防篡改的(客户端没有做任何防篡改),但它需要实际修改Javascript或队列数据结构,而不仅仅是按顺序修改响应改变处理顺序。为了使事情更加防篡改,您必须将更多的决策权转移到无法篡改的服务器上。

这是一个简单的基于promise的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/

相关问题