2012-05-10 35 views
2

我在這裏解決一些難題。如何在不知道服務器時間的情況下使用DateDiff?

您有一個作爲參數傳遞給服務器的時間戳。例如2012-5-10 14:55。 如果從給定的時間過去30秒後你會如何看待並返回truefalse

規則:

  1. 不能使用當前的服務器時間來檢查如果有30秒通過,因爲時間戳來自世界任何地方,永遠是錯的。

  2. 在這種情況下,您始終可以信任傳遞給服務器的參數時間戳。

在ColdFusion 9中(如果有的話)如何做到這一點?

回答

3

嗯....你的問題是,你不知道延遲。從收到時間戳的時間開始,您可以計數30秒 - 但這可能是時間戳創建後的幾秒鐘。

你可以...算30秒容易夠

sleep(30000); //1000 miliseconds = 1 second. 30k = 30 seconds 

因此,一旦你得到了var你可以「等待」 30秒,然後做一些事情。但從你的問題來看,你似乎需要從創建時間戳(在客戶端上創建)開始準確的30秒。你也許不能說確切的原因是:

  1. 2個時鐘不同步
  2. 你不能弄清楚請求的延遲。
  3. 即使你可以,由於你不控制客戶端,你將有麻煩保證的結果,因爲HTTP是無狀態的而不是實時的。

如果你可以指定一個HTML5瀏覽器,你可以使用websockets來做到這一點 - 它實際上是爲它祈求:)但這是我能想到的唯一真正的解決方案。

+0

是的,需要從時間戳確切的30秒。你所說的一切都是有道理的,我的結論是一樣的......除非我把時間存儲在DB/Ram中。所以在這裏......如果我第一次請求進來看服務器時間,並採取這個請求開始,也許在那裏!我的問題是現在我的應用程序在我的時區以外使用,所以請求似乎總是超時。我確信應用程序的處理方式不同。 – Prometheus

+0

另一種方法。用戶首先發出請求> GET TIME。然後他們在第二次電話中使用這段時間。 – Prometheus

+0

如果你有一個websocket,你可以發送一個事件併發送你的時間戳給它,然後讓服務器啓動併發送30秒的標記....它會關閉幾毫秒,但儘可能的接近你可以得到的在瀏覽器中。 –

1

您不指定傳遞給服務器的參數是API請求,表單提交還是ajax請求等,因此在另一端會有不同的實現。但是,ColdFusion服務器端應該非常相似,並且基本上有三個問題;時區,時差和延遲。

要解決時區問題,您可以要求將參數作爲UTC時間傳遞。當在ColdFusion比較時候,你會做這樣的事情:

<cfif DateDiff("s", Variables.PassedTimestamp, DateConvert("Local2UTC", Now())) EQ 30> 
    <!--- Exactly 30 seconds difference between timestamps ---> 
</cfif> 

但是如果發給你的時間與您的服務器上的時間同步,你不知道。爲了解決這個問題,你可以提供一種方法讓另一端查詢你的時間,並相應地調整他們的時間或者用你自己的時間回覆你的時間。

那個時間同步和最初討論的時間戳發送都會受到延遲的影響。通過網絡進行的任何通信都會受到延遲的影響,延遲時間也不盡相同。位置和Internet連接類型可能比協議類型具有更多的影響。你可以做一些事情,例如ping另一端以獲得響應時間,然後將其減半並將其添加到時間戳,但這仍然是一種aproximation,並不是所有服務器都會響應ping。

此外,您的服務器和另一端的代碼也會引入延遲。爲了減少這種情況,您希望另一端儘可能快地計算時間戳,儘可能接近請求的末尾,並使用您的代碼儘快計算時間戳。這可以通過將請求時間設置爲儘可能接近您的頂層Application.cfm | cfc來使用ColdFusion完成。

<cfset Request.Now = Now()> 

然後檢查代碼更改爲:

DateDiff("s", Variables.PassedTimestamp, DateConvert("Local2UTC", Request.Now)) 

相反,如果你想循環,直到30秒已經過去了,然後作出反應,注意,你的反應會不會出現發生在30秒後,因爲延遲會延遲響應回到另一端。準確地說30秒是不可能的,但是你要採取措施讓你更接近你。如果你只需要看看是否已經過去了大約30秒,那就足夠了。

相關問題