我想在sinatra中編寫一個簡單的問答遊戲,我需要爲所有用戶(大堂狀態,聊天消息等)提供可訪問的公共對象。問題是Sinatra在每次請求和對象變爲初始狀態後重新加載代碼。任何人都可以給我一個建議如何實現它?在Sinatra請求之間共享Ruby變量
4
A
回答
8
那麼,這個話題有點棘手。西納特拉其實並不重置服務器狀態:
require 'sinatra'
GlobalState = {}
GlobalState[:some_counter] = 0
get '/' do
response = "GlobalState[:some_counter]: #{GlobalState[:some_counter]}"
GlobalState[:some_counter] += 1
response
end
此代碼有什麼不妥:如果你運行它,並去http://localhost:4567
你會看到GlobalState[:some_counter]
增加預期。
但它不鼓勵出於以下原因,這主要涉及到應用程序的Web性質:
- 由於數據被存儲在一個Ruby對象,如果停止服務器,你鬆數據。但是,如果您不需要持久數據,這不是問題
- 當您運行Web應用程序時,通常您的應用程序同時存在實例,以便同時處理多個請求。有幾種方法可以實現它:
- 叉:同一應用程序的多個進程。它們不共享內存,所以Ruby全局狀態變量變得無用
- 線程:線程共享內存,因此您可以訪問全局狀態,但是您必須管理對同一全局對象的併發訪問,並且具有不重要的後果
- 無法將數據關聯到用戶,反之亦然:這是因爲HTTP不提供用於狀態保留的方法(它是stateless protocol)。爲了解決這個問題,你需要兩種:
- 客戶端數據存儲:餅乾,HTML5本地存儲...
- 服務器端數據存儲:會話(不是真正的服務器端只,你需要至少到會話關聯到各個客戶端,通常存儲會話ID添加到餅乾)
出於這些原因,網絡應用程序數據管理是不平凡的。無論如何,不要擔心,你不必重新發明輪子;該解決方案在手:
- Sinatra cookies用於客戶端數據存儲
- Sinatra sessions客戶端 - 服務器數據共享
- 數據庫實現數據持久化
0
如果沒有某種類型的持久存儲,沒有辦法做到這一點。您必須將信息存儲在數據庫或cookie中。
相關問題
- 1. 在Sinatra條件和請求塊之間共享數據
- 2. Apache2 :: RequestUtil ::在不同的請求之間共享變量嗎?
- 3. 在Web請求之間共享資源?
- 4. PHP $ _SESSION在請求之間不共享
- 5. Pyramid中的所有請求之間共享的全局變量
- 6. Rails全局變量:是http請求之間的全局變量共享嗎?
- 7. PHP和請求之間共享資源
- 8. 在PHP文件之間共享變量
- 9. 在類之間共享變量
- 10. 在UITabBarController視圖之間共享變量
- 11. 在Go主機之間共享變量
- 12. 在函數之間共享變量
- 13. 在PowerShell和C#之間共享變量
- 14. 在HTML頁面之間共享變量
- 15. 在方法之間共享變量
- 16. 在python和php之間共享變量
- 17. 在C#和C++之間共享變量
- 18. 在makefiles之間共享變量
- 19. 在less和coffeescript之間共享變量?
- 20. 在bash腳本之間共享變量
- 21. C++在對象之間共享變量。
- 22. 在兩個lambda之間共享變量
- 23. 在兩個winforms之間共享變量
- 24. 在進程之間共享變量
- 25. 在類之間共享變量QT
- 26. 在QStackedWidget頁面之間共享變量
- 27. 在WordPress和CodeIgniter之間共享變量
- 28. 在類C++之間共享變量?
- 29. joomla在模塊之間共享變量
- 30. angularjs在函數之間共享變量
在Web服務的發展,一個一般應努力使用進程間持久性機制(如數據庫,共享緩存)。Sinatra不會爲每個請求「重新加載代碼」,但它會創建新的對象 - 這將會有新的實例變量。如果使用全局/共享類變量或對象來維護狀態,則可能有*限制*「成功」,但這不是* * *是Web服務的首選機制,因爲它在進程重新啓動時很容易丟失數據,並且不會傳播多個前端進程之間的信息。 – user2864740
感謝您的快速回復。看來我需要設置一個數據庫。 –