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