基于workerman開發(fā)了一個客服系統(tǒng),訪客端是用的web+flash,客服使用as3寫的,假設客服(a電腦)和訪客(b電腦)正在通話,然后我把客服所在a電腦的網絡關閉掉,訪客(b電腦)那邊按理應該收到客服離線的消息才對,但是訪客一直都沒收到客服離線消息,直到我把客服所在a電腦的網絡連接上,此時訪客(b電腦)就會收到客服的離線消息。
【 對于實時性要求很高的場景,需要客戶端回應心跳,比如服務端給某個客戶端發(fā)了心跳,如果一段時間(比如10秒)沒收到客戶端的心跳回復就認為鏈接斷開了,服務端就關閉鏈接 】這個心跳該如何做呢?
【記得workeman中有那個pingpang的心跳檢測?是不是呢?】
這個和TCP傳輸層協(xié)議的實現(xiàn)有關!
非正常關閉對端可能無法立刻感知或者永遠無法感知
a端非正常關閉(斷電、把網線等)b端不會立刻感知到的,如果二者直接一直沒有通信數(shù)據(沒有keep_alive或者數(shù)據交互),則b端永遠檢測不到a已經斷開,這個是TCP的自身機制。
無法立刻感知或者無法感知的原因
a端非正常關閉,b端如果有向a端發(fā)送通訊數(shù)據(或者有keep_alive),這時很可能會發(fā)送超時,然后TCP層會自己會重試,(重試時機及次數(shù)等由系統(tǒng)參數(shù)決定),重試多次無果后才會關閉鏈接(這時服務端才得到鏈接斷開的通知,觸發(fā)onClose),從a端非正常關閉到判斷鏈接斷開如果依賴TCP本身的機制可能要持續(xù)至少10分鐘才能完成,也就導致b端很久才能感知(如果之間沒有通訊則永遠無法感知)。
要求實時檢測解決方案-應用層心跳
如果對于檢測鏈接是否可用實時性要求很高,需要在應用層面做心跳檢測,而不是依賴與TCP本身的機制。例如應用每10秒中發(fā)送一個心跳給客戶端,客戶端收到心跳后立刻返回一個回復,如果服務端心跳發(fā)出后一段時間(假如也是10秒)后客戶端并沒有回應心跳,則判斷客戶端鏈接已死,就直接斷開鏈接。
workerman里如何解決
更新下代碼 版本2.1.2 或者 版本2.1.3都可以
只更新了 applications/XXX/Bootstrap/Gateway.php 和 conf/conf.d/Gateway.conf 兩個文件
在 http://wtbis.cn/workerman下載
配置 conf/conf.d/Gateway.conf
中設置
ping_interval = X
其中X代表gateway多長時間向客戶端發(fā)送一次心跳數(shù)據,單位為秒
設置向客戶端發(fā)送的心跳請求數(shù)據,用文件保存,這里設置成文件的路徑,例如
ping_data = ../applications/Chat/ping.data
其中ping.data文件生成方式參考http://wenda.workerman.net/?/question/34
設置
ping_not_response_limit = N
代表客戶端連續(xù)N次沒有回應心跳數(shù)據就斷開鏈接,N可以為1
注意:開啟workerman心跳檢測后客戶端必須回應心跳數(shù)據,不然會導致鏈接斷開
這里有一個基于workerman開發(fā)的客服系統(tǒng)源碼,可以直接用。
群主,如果我的ping.data 里面這樣寫{"type":"Heartbeat","content":"ping","time":1409310503}/n ,那么我在客戶端只要接受到的消息的type=Heartbeat時,就返回一個{json}/n 格式的數(shù)據就可以了嗎?服務器端不需要接收一下嗎 ???還是服務器上已經做過接受處理了?如果接受并處理了是在那里處理的?請教一下