2014-02-09 23 views
0

我正在使用Meteor爲與外部硬件系統(即機器人)緊密耦合的服務器創建動態客戶端界面。服務器可以處於三種不同狀態之一(A/B/C),但需要一段時間才能在三種狀態之間轉換。根據所處的狀態,我希望客戶端用戶界面顯示不同的屏幕。用於在長時間運行的服務器轉換期間更新用戶界面的流星模式

我已經通過將服務器狀態存儲在Meteor集合中並將此狀態變量發佈給所有連接的客戶端來解決此問題。客戶可以調用Meteor方法來要求服務器改變狀態(例如,A-> B)。結果,一旦服務器狀態改變,新的屏幕顯示在客戶端上。我使用的客戶端模板,這個狀態變量是這樣的:

<template name="root"> 
    {{#if equals server.state "A"}} 
    {{> UI_for_state_A}} 
    {{/if}} 
    {{#if equals server.state "B"}} 
    {{> UI_for_state_B}} 
    {{/if}} 
    etc.  
</template> 

然而,在服務器上的狀態轉變可向上10秒即可完成。在此期間,客戶端仍在顯示舊屏幕。客戶端用戶界面感覺非常反應。我也嘗試讓服務器在狀態轉換開始時更新集合中的狀態變量,但是這會導致客戶端在服務器準備就緒之前切換到新的屏幕,這意味着沒有任何數據尚未填充或可用於新的屏幕。

我想要的是客戶端在服務器處於轉換狀態時顯示「加載」頁面,以便用戶知道正在進行的操作,但不允許在轉換過程中單擊任何按鈕。

流星做這種UI同步的最佳做法是什麼?

更新:可以有多個連接的客戶端,它們都必須與服務器的狀態同步。另外,由於外部因素,服務器可能會改變其狀態,而不一定是客戶端事件。所有這些狀態更新都需要傳播給所有客戶端。

回答

2

這聽起來像你只需要引入第三個加載狀態。在開始狀態轉換之前,將服務器集合中的狀態值設置爲此加載狀態,然後在完成後將其設置爲最終的更改狀態。

if (Meteor.isClient) { 
    Meteor.methods({ 
    yourMethodName: function() { 
     States.insert({state: "loading", timestamp: Date.now()}); // or however you would set the state on the server 
    } 
    }); 
} 

這將使你的方法使用延遲: -

請注意,您的應用程序仍然可能會感到有點呆滯上注意到上述負荷狀態,所以你應該簡單地設置狀態在客戶端上定義方法存根補償,因此客戶端將立即進入加載狀態,而不是等待服務器發送發佈更新。

+0

這似乎只有在狀態被追加到集合時才起作用。如果我只使用單例狀態,那麼有時客戶端方法的更新似乎會破壞服務器端的更新,並且客戶端可能永遠陷入「加載」狀態。 –

+0

用於更新狀態的客戶端和服務器代碼應該看起來完全相同。如果您通過插入並檢索最新狀態來更改狀態,我只是向您展示一個示例。如果你以其他方式做,你應該確保你的服務器方法和客戶端方法存根以相同的方式進行狀態改變。 – sbking

+0

對,我在服務器和客戶端有相同的代碼: 'State.update(stateid,{state:「A」})' 這種方法的問題是如果客戶端更新它可能會出現爭用條件服務器完成後。狀態可能卡在「加載」狀態。您的解決方案可以通過加蓋狀態來避免競爭狀況,但是您有一個不利因素,那就是您有一個不斷增長的收集,需要以某種方式進行修剪。 –

相關問題