2016-08-01 31 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/