(PECL event >= 1.8.0)
EventHttpConnection::setCloseCallback — 設定連線關閉的回呼函式
callback
連線關閉時會呼叫的回呼函式。應符合以下原型:
無回傳值。
範例 #1 EventHttpConnection::setCloseCallback() 範例
<?php
/*
* 設定關閉連線回呼函式
*
* 此腳本使用 HTTP API 處理已關閉的連線。
*
* 使用方式:
* 1) 啟動伺服器:
* $ php examples/http_closecb.php 4242
*
* 2) 在另一個終端機啟動客戶端。類似 Telnet 的
* 工作階段應如下所示:
*
* $ nc -t 127.0.0.1 4242
* GET / HTTP/1.0
* Connection: close
*
* 伺服器將輸出類似以下內容:
*
* HTTP/1.0 200 OK
* Content-Type: multipart/x-mixed-replace;boundary=boundarydonotcross
* Connection: close
*
* <html>
*
* 3) 強制終止客戶端連線,
* 例如,結束程序,或直接按下 Ctrl-C。
*
* 4) 檢查伺服器是否呼叫了 _close_callback。
* 腳本應將字串 "_close_callback" 輸出到標準輸出。
*
* 5) 檢查伺服器的程序是否沒有孤立的連線,
* 例如,使用 `lsof` 工具。
*/
function _close_callback($conn)
{
echo __FUNCTION__, PHP_EOL;
}
function _http_default($req, $dummy)
{
$conn = $req->getConnection();
$conn->setCloseCallback('_close_callback', NULL);
/*
透過啟用 Event::READ,我們可以保護伺服器免受未關閉連線的影響。
這是 Libevent 的一個特性。該函式庫會在此連線上停用 Event::READ 事件,
因此伺服器不會收到已終止連線的通知。
所以每次客戶端強制終止連線時,我們都會得到一個孤立的
連線。例如,以下是客戶端終止連線後 `lsof -p $PID | grep TCP`
命令的一部分:
57-php 15057 ruslan 6u unix 0xffff8802fb59c780 0t0 125187 socket
58:php 15057 ruslan 7u IPv4 125189 0t0 TCP *:4242 (LISTEN)
59:php 15057 ruslan 8u IPv4 124342 0t0 TCP localhost:4242->localhost:37375 (CLOSE_WAIT)
其中 $PID 是我們的程序 ID。
以下程式碼塊修正了這類孤立的連線。
*/
$bev = $req->getBufferEvent();
$bev->enable(Event::READ);
// 我們必須明確地釋放它。請參閱
$bev->free(); // 我們必須明確地釋放它
$req->addHeader(
'Content-Type',
'multipart/x-mixed-replace;boundary=boundarydonotcross',
EventHttpRequest::OUTPUT_HEADER
);
$buf = new EventBuffer();
$buf->add('<html>');
$req->sendReply(200, "OK");
$req->sendReplyChunk($buf);
}
$port = 4242;
if ($argc > 1) {
$port = (int) $argv[1];
}
if ($port <= 0 || $port > 65535) {
exit("無效的埠");
}
$base = new EventBase();
$http = new EventHttp($base);
$http->setDefaultCallback("_http_default", NULL);
$http->bind("0.0.0.0", $port);
$base->loop();
?>