我想在手機app內(nèi)設計一個群聊的。不知道服務器該如何設計?
請walkor大神回答下。
拜謝
首先下載最新版本的workerman-chat
數(shù)據(jù)流程及實現(xiàn)步驟:
1、客戶端鏈接到workerman,并進行websocket握手,onConnect代碼可以復用workerman-chat的onConnect。onConnect主要工作就是生成一個唯一的uid(實際上是客戶端的id,不要用用戶的實際uid,因為每個uid可能進入了多個房間,對應多個socket鏈接),并進行存儲(Gateway::storeUid)綁定(Gateway::notifyConnectionSuccess)
2、客戶端向服務端發(fā)送type為login的json數(shù)據(jù),包含了所在房間號$room_id,workerman獲得room_id,設置$_SESSION=$room_id,以便下次該客戶端發(fā)來請求能夠直接從$_SESSION獲得$room_id。另外還要將該uid(實際上是客戶端id)保存到$room_id對應的所有客戶端id列表,以便群聊時向這些客戶端id發(fā)送數(shù)據(jù)。login的數(shù)據(jù)中應該還包含用戶的user_id,通過這個user_id能夠從存儲中獲得用戶名,然后可以將這個用戶名也放到$_SESSION中,方便后續(xù)請求直接使用
3、當客戶端發(fā)來type為群聊的消息時,我們能直接從$_SESSION中獲取$room_id ,也就能通過$room_id獲取所有的客戶端id($clientid_array),然后調(diào)用Gateway::sendToAll($message, $clientid_array);就向$clientid_array指定的$room_id的所有客戶端發(fā)送消息了
3、當客戶端斷開時,注意要將該客戶端id從$room_id對應的客戶端列表中刪掉
注意:
以上重要的一點就是uid是客戶端的id,全局唯一標識一個socket鏈接,以便區(qū)分和哪個鏈接通訊,和用戶uid沒有直接關系
$_SESSION是和socket綁定的(和用戶user_id之間沒有直接聯(lián)系),即每個socket鏈接會有一個$_SESSION,里面可以存儲用戶的user_id、user_nick、room_id等信息,以后該socket上的請求可以直接使用$_SESSION的數(shù)據(jù),避免了每次讀取數(shù)據(jù)庫的開銷
多人聊天室的例子已經(jīng)在計劃當中,預計9月份會發(fā)出來。
現(xiàn)在workerman-chat已經(jīng)支持多房間了,并且支持了私聊、掉線重連、服務端心跳機制
http://github.com/walkor/workerman-chat