web socket 心跳包的實現方案05/30/2010
現在網絡環境錯綜復雜,socket心跳包是獲得健康強壯的連接的有效解決方案,今天,我們就在web socket中實現心跳包方案,是的,盡管我們只是做一個簡單的聊天室,但我們讓他穩定可靠一些一點也沒有錯。
我的心跳包方案很是簡單,原理就是間隔發送心跳包數據給服務器,服務器在一定時間內發回心跳包響應,對比超時限定,如果超過設定的超時時間,則認為當前與服務器的websocket連接已經斷開,關閉當前web socket連接,善后處理,例如重新連接,或者彈出提示……
比較有用的核心代碼是這樣子的:
function keepalive( ws ){ var time = new Date(); if( last_health != -1 && ( time.getTime() - last_health > health_timeout ) ){ //此時即可以認為連接斷開,可設置重連或者關閉連接 $("#keeplive_box").html( "服務器沒有響應." ).css({"color":"red"}); //ws.close(); } else{ $("#keeplive_box").html( "連接正常" ).css({"color":"green"}); if( ws.bufferedAmount == 0 ){ ws.send( '~H#C~' ); } } } |
這就是心跳函數,發送心跳包和檢測心跳健康度。我們將其植入到websocket的onopen事件中,來開啟心跳檢測。像這樣:
var ws = new WebSocket( to_url ); ws.onopen=function(){ $("#statustxt").html("connected."); $("#send_btn").attr("disabled", false); heartbeat_timer = setInterval( function(){keepalive(ws)}, 1000 ); } |
是的,這樣子就可以實現web socket的心跳包,這里有些類似於多線程的發送方式,在發送心跳包的同時,並不影響正常的數據通信,我們的例子還是以上次的websocket聊天室來改進,我們可以發現,心跳包運行過程中,並不會干擾到我們的正常聊天。服務端我也進行了一些修改,原理類似,在超過一定時間內都沒有收到客戶端發來的心跳包,則認為該客戶端已經掉線,關閉連接,收回資源。
Demo在這里:http://img.zendstudio.net/libs/websocket/chat/demo2.html
現在,有一個新的問題出現,如果我們要用php socket來模擬心跳包技術,該怎么實現?各位路過的朋友請多指教,感恩戴德。
- 3條評論 ▼
您好!代碼字體很舒服,能告訴我是哪種字體嗎?我用的是zend studio 5.5.1,可以修改成文章中的代碼字體嗎?謝謝!
無形中加重負擔了吧,php的socket效率真不怎么樣
WebSocket.class.php
private $Connection=array();
$c = new Connection;
$c->sock = socket_accept($this->Master);
if $buffer == ‘~H#C~’ $c->atime=time()
$Connection[] = $c;
then
while($true){
$time = time();
foreach ($Connection as $c)
{
if ($c->atime + 20 sock);}
}
}
Connection.class.php
class Connection
{
public $sock;
public $atime = time();
}
應該看得懂吧,也不知道行不行,明天去測試下…
為了穩定可靠,這個負載犧牲是必須的。php socket目前屬於玩具級水平,我僅將其用於測試(BTW:實際上我們的實際生產中也有使用php socket來作為服務器,只是結合了C,所以也不完全屬於php socket范疇了)。偽代碼意思看的懂。