最近因為網站要支援nginx的動態負載平衡,因此要去掉cppcms內建的session機制。就順便研究了一下cppcms的application。
準確的講,研究的是application類的子類的生命週期. 按照cppcms的規則,我們必須自己從application繼承出自己的類,比如MyApp, 邏輯上,這個類的對象會被緩衝到application pool中,代表了一個應用程式。
cppcms的設計支援多個application運行在一起,也就是通過http://domain:port/(具有相同的domain和連接埠)能夠訪問到多個web apps。
想法很大,不過我用不著多個應用在一個進程裡面運行,真要是有多個應用,我肯定會放在不同的進程裡面使用,進程隔離,會比較安全。防止一個web app寫得不好,crash導致其他app也完蛋。 雖然多個application運行在不同的進程,意味著監聽了各自的連接埠,訪問的時候可能URI不一致,不過前面加上Nginx就可以將之統一起來。
既然MyApp代表一個web application,因此它的對象就只能有一個,建構函式也只能被調用一次,預設情況下,經過測試,是在第一次web請求到達的時候被建立出來的。
MyApp可以改寫繼承來自application的虛函數init,這個函數當每次web請求到來都會被調用。
注意
1.如果有全域的資料,現在可以放在MyApp裡面作為成員變數. 不過如果涉及到既讀又寫的話,還是應該使用線程同步操作保證多安全執行緒。
因為通過日誌列印線程ID,可以證明的確是多線程調用MyApp的方法。實驗代碼寫在init函數中:
void MyApp::init() { thread::id current_thread_id = boost::this_thread::get_id(); BOOSTER_NOTICE("MyApp) << "enter init" << " thread id:" << current_thread_id; }
2.為了打造一個stateless的restful web app, 不要將session等資料儲存在MyApp的成員變數中。可以寫到真正的session server中,或者簡化起見,直接寫到mongodb中。以後每次再通過key讀出來。key存放在用戶端的cookie中,當使用者登入驗證通過後,可以通過調用繼承自application::response().set_cookie 函數來將自己產生的key儲存在cookie中,然後返回到瀏覽器端,瀏覽器可以將cookie儲存起來。
請看例子代碼:
cookie c("my_session", user->oid, 36000, "/");response().set_cookie(c);
多執行緒模式還未深究,目前只知道cppcms內部使用了線程池。