建了一個(gè)群group表,主鍵為group;建了一個(gè)群成員表group_membser,關(guān)聯(lián)group_id和用戶uid
我要邀請(qǐng)一個(gè)用戶進(jìn)群,前端請(qǐng)求http接口,把group_id和uid寫(xiě)入group_member表,那什么時(shí)候用joinGroup方法,把這個(gè)uid加入到群組呢?
我的思路:在Event.php中onWebSocketConnect方法里去執(zhí)行,查詢group_membser表中,當(dāng)前用戶所有的分組信息,然后循環(huán)調(diào)用joinGroup方法,把當(dāng)前用戶加進(jìn)去,但總感覺(jué)怪怪的,想問(wèn)下大家是怎么做的?
未在線時(shí)收到的消息怎么在剛上線的時(shí)候發(fā)送?
對(duì)于1:
你的做法是常規(guī)的一種,依靠數(shù)據(jù)庫(kù)做關(guān)聯(lián),用戶登錄的時(shí)候,綁定在gatewayworker的內(nèi)存里,然后gatewayClient的sendGroup,內(nèi)部群發(fā)。 基本應(yīng)該是這樣的
對(duì)于2:
應(yīng)該在登錄時(shí)候,http拉取歷史未讀的私聊消息。
特別的對(duì)于群聊
,我覺(jué)得群聊消息應(yīng)該是一張公共表,不需要記錄到群里的每個(gè)用戶的未讀消息。群成員登錄的時(shí)候http請(qǐng)求一次性拉取最近幾天的消息(qq就是這樣做的,想要拉取更多歷史消息,請(qǐng)求http拉取,并且攜帶群聊消息最老的id和limit)
對(duì)于1:
public static function onWebSocketConnect($client_id, $data)
{
$token=isset($data['get']['token'])?$data['get']['token']:'';
if (empty($token)) {
Gateway::closeClient($client_id);
}else{
try {
$jwtData= JwtToken::verify(1,$token);
if(isset($jwtData['extend']['id'])){
$uid=$jwtData['extend']['id'];
Gateway::bindUid($client_id,$uid);
$_SESSION['uid']=$uid;
$groupData=GroupMember::getGroupIdByUid($uid);
if(!empty($groupData)){
foreach ($groupData as $group){
Gateway::joinGroup($client_id,$group['group_id']);
}
}
}else{
Gateway::closeClient($client_id);
}
}catch (\Exception $e){
Gateway::closeClient($client_id);
}
}
}
不知道這種發(fā)放耗不耗性能
對(duì)于2:
我也是用http去拉取的
剛好最近做了跟你類(lèi)似的項(xiàng)目,
對(duì)于1:我也是跟你一樣的做法,當(dāng)我不是寫(xiě)在event 里面的,我是等用戶通過(guò)鑒權(quán)成功之后,調(diào)用http接口,在接口里面做的for循環(huán)綁定,
對(duì)于2:這個(gè)其實(shí)要看你的需求了,其實(shí)對(duì)于群消息處理起來(lái)賊頭大,因?yàn)槲覀兪莂pp上有聊天功能,所以我們的需求是沒(méi)網(wǎng)也要能看消息.所以消息都是緩存到本地,服務(wù)端用的擴(kuò)撒寫(xiě)機(jī)制,好處就是對(duì)群消息的離線處理機(jī)制很簡(jiǎn)單,壞處就是存的時(shí)候很麻煩,哈哈哈,如果用擴(kuò)散讀,那就是好處就是存消息的時(shí)候很簡(jiǎn)單,查詢的時(shí)候就很麻煩. 我是這樣設(shè)計(jì)的有個(gè)消息總表,然后有個(gè)離線消息表,每次群里有人發(fā)言,都要給每個(gè)用戶寫(xiě)一條數(shù)據(jù)到離線表里面,不管用戶在不在線,然后等前端處理完成之后,通知我,在從表里面刪除對(duì)應(yīng)數(shù)據(jù).這樣就能防止漏發(fā),同時(shí)前端也要處理消息去重,
有個(gè)網(wǎng)站,http://www.52im.net/ 這里面都是IM 相關(guān)的帖子,啥的,你可以看看,我當(dāng)時(shí)也是借鑒他們的思路,然后用戶重新斷線重連之后,只需要返回每個(gè)聊天的最后一條消息和未讀消息條數(shù),用戶進(jìn)入某個(gè)聊天再去拉取離線消息庫(kù)里面的消息,成功返回ack ,離線消息庫(kù)拉取完之后,后面的數(shù)據(jù)就走本地緩存了,