2013-12-09 24 views
2

從網站的例子:是否可以在vibe.d中全局存儲當前會話信息? (dlang)

import vibe.d; 

void login(HTTPServerRequest req, HTTPServerResponse res) 
{ 
    enforceHTTP("username" in req.form && "password" in req.form, 
     HTTPStatus.badRequest, "Missing username/password field."); 

    // todo: verify user/password here 

    auto session = res.startSession(); 
    session["username"] = req.form["username"]; 
    session["password"] = req.form["password"]; 
    res.redirect("/home"); 
} 

void logout(HTTPServerRequest req, HTTPServerResponse res) 
{ 
    res.terminateSession(); 
    res.redirect("/"); 
} 

void checkLogin(HTTPServerRequest req, HTTPServerResponse res) 
{ 
    // force a redirect to/for unauthenticated users 
    if(req.session is null) 
     res.redirect("/"); 
} 

shared static this() 
{ 
    auto router = new URLRouter; 
    router.get("/", staticTemplate!"index.dl"); 
    router.post("/login", &login); 
    router.post("/logout", &logout); 
    // restrict all following routes to authenticated users: 
    router.any("*", &checkLogin); 
    router.get("/home", staticTemplate!"home.dl"); 

    auto settings = new HTTPServerSettings; 
    settings.sessionStore = new MemorySessionStore; 
    // ... 
} 

但可以說,我沒有想通過ServerResponse我的整個程序到每一個功能。例如,如果res.session存儲當前用戶的ID,該怎麼辦?這是經常使用的,所以我不希望這通過每個函數。我如何在全球存儲此會話信息?假設有多個用戶在使用該網站。

+0

Khm ...也許我們需要振動標籤:) – DejanLekic

+0

我知道!我嘗試回答一些其他問題,以獲得所需的聲譽。不是一個大回信,所以如果你想這樣做,我會很感激它:) – carboncomputed

+0

我會嘗試添加它,但我認爲我的代表還不夠高... –

回答

3

雖然有些氣餒,但這是可能的。

解決方案

你不能簡單地存儲它在全球範圍,因爲沒有這樣的東西作爲「全球性」會議 - 它總是特定要求的上下文。即使在D中默認全局線程爲局部變量也沒有幫助,因爲多個光纖共享相同的執行線程。

對於這樣的任務,vibe.d提供了TaskLocal模板,它可以完成你想要的任務。我沒有嘗試過,但期望TaskLocal!Session session「只是工作」。

請從文檔注意這兩個警告:

不過要注意,每個TaskLocal變量會增加使用任務本地存儲任何任務的內存佔用。也有訪問TaskLocal變量,比線程局部變量更高的開銷,但一般還是O(1)

FiberLocal情況下都必須聲明爲靜態/全局線程局部變量。將它們定義爲臨時/堆棧變量將導致崩潰或數據損壞!

異議

根據我的經驗,但是,它仍然更好的明確,儘管通過小打字不便傳遞所有這樣的背景下。使用全局變量是有原因的,因爲隨着程序規模的增加,跟蹤模塊之間的依賴關係和測試代碼變得難以避免。現在下降到便利的誘惑可能會導致以後很多頭痛。爲了最大限度地減少額外的輸入和簡化代碼維護,我建議改爲定義struct Context { ...},它將包含請求/會話指針,並且會定期傳遞。

相關問題