請教下各位大神,下方是我寫的偽邏輯,看起來沒問題,但實際設(shè)備上下線頻繁時,在線狀況是錯誤的,調(diào)試后發(fā)現(xiàn)是onMessage
中Gateway::closeClient($id);
的操作觸發(fā)onClose
,是在onMessage
后續(xù)將設(shè)備設(shè)置為在線之后。
也就是說,我在設(shè)備上線后,手動斷開老的連接,將狀態(tài)設(shè)置為離線,再將狀態(tài)設(shè)置為在線的操作由于onClose
并不會馬上執(zhí)行導(dǎo)致順序反轉(zhuǎn)
function onMessage($client_id, $data){
//獲取設(shè)備發(fā)送的業(yè)務(wù)ID
$id = $data['id'];
//如果之前已經(jīng)有在線的則踢掉,如意外掉線,心跳未斷掉的情況下
$ids = Gateway::getClientIdByUid($id);
foreach ($ids as $id) {
Gateway::closeClient($id);
}
//存入$_SESSION,在onClose時判斷存在ID則離線
$_SESSION['id'] = $id;
//綁定client_id和業(yè)務(wù)ID
Gateway::bindUid($client_id, $id);
//持久化在線離線狀態(tài),例Redis
Redis::hSet($id,'online', 1);
//推送設(shè)備在線至客戶端
Gateway::sendToGroup($id, 'online|1');
}
function onClose($client_id){
if(isset($_SESSION['id'])){
$id = $_SESSION['id']
Redis::hSet($id,'online', 0);
Gateway::sendToGroup($id, 'online|0');
}
}
打算在onClose
里isUidOnline
,如果用業(yè)務(wù)ID能查到有在線的連接,就不設(shè)置為離線。
不知道在onClose
里自己算不算在線連接,如果算話改用getClientIdByUid,感覺沒問題。
各位有沒有更優(yōu)雅的方法~