關鍵技術支援:監聽器、unload(解除安裝)事件、load(加載)事件、session、application
一、理論知識:
1.session在使用者進入伺服器時建立。
2.application生命周期與伺服器同在。
3.監聽器可以捕獲到session、application的建立與銷毀。
二、理論實作:
1.監聽器捕獲到application建立時,設定線上人數為0,存儲在application中。
2.捕獲到session建立時,application中的線上人數+1。
3.捕獲到session銷毀時,application中的線上人數-1
三、主要技術難點:
1.使用者直接關閉浏覽器\不經過登出這一步驟
2.不存在頁面關閉事件與浏覽器關閉事件
解決方案
1.首先了解頁面重新整理原理與關閉頁面(浏覽器)原理重要部分
頁面重新整理:觸發unload(解除安裝)\load(加載)事件
關閉頁面:觸發unload(解除安裝)事件
2.由上述可知:關閉頁面不會觸發load事件
3.解決理論:
<1>我們可以在window執行unload事件時,向伺服器發送生命中最後一個請求,請求伺服器清除目前的session,此處就可以讓監聽器捕獲到session銷毀。(存在重新整理問題—技術難點2)
解決重新整理問題:
<2>由1可知,頁面重新整理時也會觸發該請求,為了避免重新整理也會删除目前的session,是以總結了上述的2。
<3>事先配置一個load事件向伺服器請求。向伺服器發送生命中最後一個請求時,用新線程執行清除session,但在執行清除指令時,先讓該線程睡眠2s。在此同時,如果是重新整理頁面,會執行load事件中的請求,請求中斷線程執行清除session的指令。如果是退出頁面則,session會被正常清除,線上人數完成-1。
注意:
如果是多使用者操作的情況下,要求保證方法、使用者、線程唯一性。
線程必須保證每次頁面關閉請求時都是全新的。
測試浏覽器:谷歌
代碼實作如下:
JavaScript
window.addEventListener('load',outWindow,false);
window.addEventListener('unload',noOutWindow,false);
function outWindow() {
$.post('${top}/login?parameter=selectCheck&check=0');
}
function noOutWindow() {
$.post('${top}/login?parameter=selectCheck&check=1');
}
Java
private String str = "0";
private HttpSession session = null;
private Thread thread = null;
public void selectCheck(HttpServletRequest request) throws ServletException, IOException {
//擷取參數
String check = request.getParameter("check");
if (check.trim().equals("1")){
session = request.getSession();
str=check.trim();
thread=new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
if (str.equals("1")){
//最終移除
session.invalidate();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}else{
str = "0";
//中斷目前線程
if (thread!=null){
//原理:調用Java異常處理機制中斷線程
thread.interrupt();
}
}
}