2013-03-11 64 views
1

我正在創建一個簡單的實時聊天應用程序,所以我必須在頁面的右側顯示chatBuddyList。 (user_id,name,email ...)和tbl_logged_user(id,user_id)。獲取登錄用戶列表PHP

用戶登錄我會將user_id添加到tbl_logged_users並在註銷時刪除該記錄。

一切都很好,但問題是與Logout。當用戶點擊logout鏈接它將工作,但有時用戶可能會自動註銷,由於會話到期,瀏覽器關閉等...

我該如何處理這種情況?什麼是實現這一目標的最佳方式?

謝謝。

我想找到最好的方法,只是因爲確切的應用程序不是一個真正的聊天基礎之一,我有一個表/ s與平均80,000記錄。投票/彗星運行時間約5-10秒。

編輯

有一些答案說關於session_id。我相信它沒有用,因爲會話超時PHP不能自動更新數據庫表,除非有新的請求。

+0

我以前做過這個。爲了解決這個問題,有必要在數據庫中寫入與客戶端最近一次聯繫的時間戳,並測試它是否早於x秒。 – fnkr 2013-03-11 09:37:28

+0

@fnkr「閒置」用戶呢。 – Red 2013-03-11 09:43:20

+0

你可以實現[SessionHandlerInterface](http://php.net/manual/en/class.sessionhandlerinterface.php)。在你的[destroy](http://php.net/manual/en/sessionhandlerinterface.destroy.php)方法中,你可以使用session_id()更新數據庫。 – mend3 2017-10-31 11:42:27

回答

2

那麼,這不是解決問題的「常用」方式,但我認爲這不是一個糟糕的解決方案:

您可以使用帶有小型Node.js serv的websocket呃例如。當用戶使用有效的會話加載頁面時,它會連接到服務器(只有兩行javascript)。當它斷開連接(關閉頁面)時,websocket消除並且服務器捕獲事件。

如果用戶關閉瀏覽器,則套接字斷開連接。如果用戶單擊註銷,則頁面重新加載,然後不再創建套接字(無效會話)。唯一的問題出現在用戶長時間打開瀏覽器並且會話過期時。那麼,在服務器中添加超時將解決此問題。

如果你正在創建一個聊天應用程序,試試websockets,你不會後悔。

+0

感謝蠻力,我想避免這樣的事情,只是因爲我沒有意識到這一點。讓我想一想'Node.js'。 – Red 2013-03-11 10:40:36

+0

那麼,你會喜歡node.js =)另外檢查出Socket.IO http://socket.io/ – TheBronx 2013-03-11 10:49:53

0

考慮一個用戶登錄,如果他在最近5分鐘內(或左右)處於活動狀態。幾乎每個網站都是這樣處理的。 您可以在用戶每次「做」什麼時間(即在客艙發送郵件)

+0

感謝您的想法,但它是聊天應用程序的情況下可靠的方式?例如:假設有3個用戶。 'User1'和'User2'互相聊天,'User3'是'idle',這三個人可以在chatList上看到3個用戶,現在'User3'在會話超時時間內被註銷,我該如何處理?任何想法? – Red 2013-03-11 09:42:53

+0

如果Ajax刷新自上次時間戳更新後超過4分鐘,您可以再次更新時間戳。 – 2013-03-11 09:49:38

+0

沒有防水的方式來註冊它。如果您每隔幾秒鐘在網絡服務器上「輪詢」新郵件(使用ajax),則可以將您的超時設置爲@ 30秒,例如 – 2013-03-11 09:50:49

-1

只是註冊一個時間戳,如果你保持一個表的會議,僅計算表活動會話的數量。

+0

你能多解釋一下嗎? (我希望這是一個答案) – Red 2013-03-11 09:46:10

+1

會話表不可靠。當用戶關閉他的窗口時,會話表將不會更新,直到您將會話「終止」(例如,使用PHP的默認超時) – 2013-03-11 09:49:46

+0

您正在使用框架嗎?你的課程去哪裏?在文件系統或數據庫?如果它是一個文件系統,你可以做$ sessionCount = count(glob(session_save_path()。「/ *」)); – priyolahiri 2013-03-11 09:50:35

1

在登錄時將會話標識存儲在表中,並定期檢查會話標識,以便狀態用戶處於聯機狀態,如果用戶關閉瀏覽器會話標識則不會匹配,然後註銷用戶。

+0

你能解釋一下嗎?如何檢查session_id? – 2014-03-17 19:59:25

2

這是我的聊天應用程序中的會話檢查器代碼。
$ CONFIG [「app:maxLatency」]是以秒爲單位的時間。在此之後,如果客戶沒有聯繫服務器,客戶端將被註銷。
你需要一個叫做用戶ID(整數),lastseen(時間戳)和SID

樣品臺表(會話ID,文本):

id  | lastseen    | sid 
-------------------------------------------------- 
123 | 2013-03-11 11:00:00  | abcdefg12345 

示例代碼:

function DeleteSessionByUserId($user_id) { 
    $user_id = mysql_real_escape_string($user_id); 
    global $CONFIG; 

    $sql = "UPDATE users SET sid = '' WHERE id = '".$user_id."'"; 
    $result = mysql_query($sql); 
    return true; 
} 

// This will delete all users with expired sessions 
function CheckAllSessionsExpired() { 
    global $CONFIG; 

    $sql = "SELECT id FROM users WHERE sid != '' AND lastseen < '".date("Y-m-d H:i:s", strtotime("-".$CONFIG["app:maxLatency"]." seconds"))."'"; 

    $result = mysql_query($sql); 
    while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { 
     DeleteSessionByUserId($line['id']); 
    } 
    return true; 
} 

// This will update the last seen timestamp in MySQL 
function UserSetSeen($user_id) { 
    $user_id = mysql_real_escape_string($user_id); 

    global $CONFIG; 
    $sql = "UPDATE users SET lastseen = '".date("Y-m-d H:i:s")."' WHERE id = '".$user_id."';"; 
    $result = mysql_query($sql); 
    return true; 
} 
+1

'CheckAllSessionsExpired'會殺死我所有的閒置用戶。 – Red 2013-03-11 10:03:40

+0

您是否每次客戶端與服務器聯繫時都運行UserSetSeen($ user_id)?我使用JavaScript來每隔1秒刷新一次消息。 – fnkr 2013-03-11 10:04:57

+0

感謝您的努力,技術上它的確定。但在我的情況下,它不實用,只是想想互聯網連接丟失,所以它將無法更新'時間戳',也不能在頁面上運行超過2次民意調查。 – Red 2013-03-11 10:10:21