使用場(chǎng)景,用戶登錄網(wǎng)站后,與workerman建立websocket連接,可以聊天了。用戶會(huì)刷新頁面,或者跳轉(zhuǎn)到此網(wǎng)站的其他頁面,現(xiàn)在workerman的邏輯是重新產(chǎn)生一個(gè)client——id,綁定uid,我的想法是用戶登錄網(wǎng)站成功后,網(wǎng)站session儲(chǔ)存在memcache里,key =session—id,,內(nèi)容userid usernane 等等,連接workerman時(shí),把sessionid傳過去,在memcahe里,通過sessionid查詢一下userid,是否存在,client_id是否存在(第一次連接workerman肯定不會(huì)存在,刷新或者跳轉(zhuǎn)頁面,時(shí)可能已經(jīng)存在了,)如果client_id存在,不再分配新的。問題出來了workernan是否允許這樣,主要改動(dòng)的workerman文件有哪些。
補(bǔ)充 與workerman連接成功后,在memcache 里,key=session_id 的value數(shù)組里增加存儲(chǔ)一下client_id
不能這樣簡單的更改client_id的機(jī)制,client_id包含了對(duì)應(yīng)連接所在的服務(wù)端IP 端口及連接編號(hào)信息,client_id屬于全局唯一某個(gè)進(jìn)程,client_id類似一個(gè)唯一的地址,這個(gè)client_id在其它進(jìn)程中被分配到是無法正常使用的,比如sendToClient($client_id, $msg),如果client_id根本沒在屬于它的進(jìn)程里,那么client_id是無法收到數(shù)據(jù)的。Gateway是可以多服務(wù)器多進(jìn)程的,連接被分配到哪個(gè)進(jìn)程是無法確定的。
client—id,包括了3個(gè)信息ip port 連接編號(hào),刷新頁面是,只有連接編號(hào)會(huì)變化,是這樣嗎。我具體化時(shí),連接編號(hào)改成userid,也就是改變clien_id的產(chǎn)生機(jī)制(預(yù)設(shè)條件是不登陸網(wǎng)站,不能聊天),這樣會(huì)出現(xiàn)什么問題,或者是workerman如何恢復(fù)一個(gè)進(jìn)程(client_id根本沒在屬于它的進(jìn)程里,那么client_id是無法收到數(shù)據(jù)的),workerman的client-id,作用就是標(biāo)識(shí)給誰發(fā)消息,想知道和進(jìn)程是怎么配合的。
刷新頁面,ip port(內(nèi)部通訊端口) 連接編號(hào)都可能變化。
client_id可以看做是一個(gè)通訊地址,上面包含了ip(省份) port(城市) 和連接編號(hào)(街道門牌號(hào))。每個(gè)ip:port對(duì)應(yīng)一個(gè)全局唯一的進(jìn)程(可以看做是實(shí)際的城市)。
假設(shè)原來client_id是ip(A省) port(B城市) C編號(hào)(門牌號(hào)),刷新頁面后這個(gè)client_id下線了。
新的連接被ip(A省) port(C城市) 對(duì)應(yīng)的進(jìn)程接受處理(被哪個(gè)進(jìn)程處理無法控制), 被分配了D編號(hào),這時(shí)如果還想用原來的client_id(通訊地址),那么當(dāng)向這個(gè)客戶端發(fā)送數(shù)據(jù)時(shí),就會(huì)發(fā)給ip(A省) port(B城市) C編號(hào)(門牌號(hào)),而這個(gè)A省的B城市進(jìn)程內(nèi)根本找不到對(duì)應(yīng)的客戶端連接,也就無法發(fā)送消息給他。
也就是改變client_id規(guī)則后,很多針對(duì)該clien_id的接口將無法使用,比如gateway::sendToClient、Gateway::closeClient、Gatway::bindUid等等。
以上的規(guī)則是GatewayWorker的規(guī)則,和workerman無關(guān),workerman里面沒有client_id的概念。
最后除非你非常熟悉GatewayWorer,否則不建議改動(dòng)GatewayWorker的代碼
我嘗試改動(dòng)ConnectionId的測(cè)試方法,變成用戶登錄網(wǎng)站的userid.去掉binduid,send to uid 簡化成遍歷所有包含某個(gè)userid的client_id。改動(dòng)的目標(biāo),能簡單最好。改動(dòng)上面的會(huì)遇到什么故障嗎?
protected function generateConnectionId()
{
// if (self::$_connectionIdRecorder >= 4294967295) {
//self::$_connectionIdRecorder = 1;
// }
// $id = self::$_connectionIdRecorder ++;
$id=$userid;//userid 是通過session——id,在memcahe,查尋到的
return $id;
}
剛剛想到一個(gè)更簡單的方法,把產(chǎn)生cliet_id的機(jī)制簡化,只包括ip,和port,不再包括ConnectionId,websocket建立連接并且成功后,關(guān)聯(lián)新的client——id和網(wǎng)站的userid,.當(dāng)業(yè)務(wù)邏輯需要用到send to uid 可以直接等于send to client——id.中間原來的有些函數(shù)可能會(huì)廢掉嗎