# swoole回調函數
[TOC=2,3]
在swoole中,一個swoole_server的擁有若干回調函數,這些回調函數決定了swoole_server的相關功能。可以通過
```php
$serv->on( string $event, mixed $callback );
```
函數來配置.
示例:
```php
class Server
{
private $serv;
public function __construct() {
$this->serv = new swoole_server("0.0.0.0", 9501);
$this->serv->set(array(
'worker_num' => 8,
'daemonize' => false,
'max_request' => 10000,
'dispatch_mode' => 2,
'debug_mode'=> 1
));
$this->serv->on('Start', array($this, 'onStart'));
$this->serv->on('Connect', array($this, 'onConnect'));
$this->serv->on('Receive', array($this, 'onReceive'));
$this->serv->on('Close', array($this, 'onClose'));
$this->serv->start();
}
}
```
全部回調函數以及相關介紹如下:
#### **1.onReceive**
描述:接收數據的回調<br>
函數原型:<br>
```php
function onReceive( swoole_server $serv, $fd, $from_id, $data );
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$fd | 連接的描述符
$from_id | reactor的id,無用
$data | 接收到的數據
說明:每當server接收到客戶端發來的數據后,就會通過onReceive回調將數據投遞給Worker。如果開啟了協議檢測,則會在收到完整數據包之后才會響應回調。注意,必須設置該回調函數,否則無法啟動服務器。
#### **2.onStart**
描述:服務器啟動的回調<br>
函數原型:<br>
```php
function onStart( swoole_server $serv);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
說明:<br>
onStart事件在Master進程的主線程中被調用。在此回調響應之前Swoole Server已進行了如下操作<br>
- 已創建了manager進程
- 已創建了worker子進程
- 已監聽所有TCP/UDP端口
- 已監聽了定時器
接下來要執行<br>
- 主Reactor開始接收事件,客戶端可以connect到Server
onStart回調中,僅允許echo、打印Log、修改進程名稱。不得執行其他操作。onWorkerStart和onStart回調是在不同進程中并行執行的,不存在先后順序。
可以在onStart回調中,將**$serv->master_pid**和**$serv->manager_pid**的值保存到一個文件中。這樣可以編寫腳本,向這兩個PID發送信號來實現關閉和重啟的操作。<br>
從1.7.5+ Master進程內不再支持定時器,onMasterConnect/onMasterClose2個事件回調也徹底移除。Master進程內不再保留任何PHP的接口。<br>
在onStart中創建的全局資源對象不能在worker進程中被使用,因為發生onStart調用時,worker進程已經創建好了。新創建的對象在主進程內,worker進程無法訪問到此內存區域,因此全局對象創建的代碼需要放置在swoole_server_start之前。<br>
#### **3.onWorkerStart**
描述:Worker進程啟動的回調<br>
函數原型:<br>
```php
function onWorkerStart( swoole_server $serv,int $worker_id);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$worker_id| Worker進程的id
說明:此事件在worker進程/task_worker啟動時發生。
> 發生PHP致命錯誤或者代碼中主動調用exit時,Worker/Task進程會退出,管理進程會重新創建新的進程
onWorkerStart/onStart是并發執行的,沒有先后順序
通過$worker_id參數的值來,判斷worker是普通worker還是task_worker。$worker_id>= $serv->setting['worker_num'] 時表示這個進程是task_worker。<br>
如果想使用swoole_server_reload實現代碼重載入,必須在workerStart中require你的業務文件,而不是在文件頭部。在onWorkerStart調用之前已包含的文件,不會重新載入代碼。<br>
可以將公用的,不易變的php文件放置到onWorkerStart之前。這樣雖然不能重載入代碼,但所有worker是共享的,不需要額外的內存來保存這些數據。<br>
onWorkerStart之后的代碼每個worker都需要在內存中保存一份
$worker_id是一個從0-$worker_num之間的數字,表示這個worker進程的ID
$worker_id和進程PID沒有任何關系<br>
#### **4.onConnect**
描述:新連接接入時的回調<br>
函數原型:<br>
```php
function onConnect( swoole_server $serv,int $fd, int $from_id);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$fd | 連接的描述符
$from_id | reactor的id,無用
說明:有新的連接進入時,在worker進程中回調。onConnect/onClose這2個回調發生在worker進程內,而不是主進程。如果需要在主進程處理連接/關閉事件,請注冊onMasterConnect/onMasterClose回調。onMasterConnect/onMasterClose回調總是先于onConnect/onClose被執行
#### **5.onClose**
描述:連接關閉時的回調<br>
函數原型:<br>
```php
function onClose( swoole_server $serv,int $fd, int $from_id);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$fd | 連接的描述符
$from_id | reactor的id,無用
說明:TCP客戶端連接關閉后,在worker進程中回調此函數。無論close由客戶端發起還是服務器端主動調用**swoole_server_close**關閉連接,都會觸發此事件。
因此只要連接關閉,就一定會回調此函數。
#### **6.onTask**
描述:task_worker進程處理任務的回調<br>
函數原型:<br>
```php
function onTask(swoole_server $serv, int $task_id, int $from_id, string $data);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$task_id | 任務ID
$from_id | 來自于哪個worker進程
$data | 任務內容
說明:在task_worker進程內被調用。worker進程可以使用swoole_server_task函數向task_worker進程投遞新的任務。可以直接將任務結果字符串通過return方式返回給worker進程。worker進程將在[onFinish](#7onfinish)回調中收到結果。注:如果serv->set(array('task_worker_num' => 8)) task_id 并不是從1-8 而是遞增的。
#### **7.onFinish**
描述:task_worker進程處理任務結束的回調<br>
函數原型:<br>
```php
function onFinish(swoole_server $serv, int $task_id, string $data);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$task_id | 任務ID
$data | 任務結果
說明:在此函數中會收到任務處理的結果,通過task_id和worker_id來區分不同的任務。
#### **8.onTimer**
描述:定時器觸發的回調<br>
函數原型:<br>
```php
function onTimer(swoole_server $serv, int $interval);
```
參數 | 描述
-------- | ---------
$serv | swoole_server對象
$interval | 定時的間隔
說明:定時器被觸發時,該函數被調用。通過interval來區分不同時間間隔的定時器。
其余回調函數請參看[swoole wiki](http://wiki.swoole.com/wiki/page/41.html)
- swoole簡介
- swoole功能概述
- 序章
- 開發必讀
- 1 環境搭建
- 1.1 環境搭建
- 1.2 搭建Echo服務器
- 2 初識Swoole
- 2.1 Worker進程
- 2.2 TaskWorker進程
- 2.3 Timer定時器
- 2.4 Process進程
- 2.5 Table內存表
- 2.6 多端口監聽
- 2.7 sendfile文件支持
- 2.8 SSL支持
- 2.9 熱重啟
- 2.10 http_server
- 附錄*server配置
- 附錄*server函數
- 附錄*server屬性
- 附錄*server回調函數
- 附錄*server高級特性
- 心跳檢測
- 3 Swoole協議
- 3.1 EOF協議
- 3.2 固定包頭協議
- 3.3 Http協議
- 3.4 WebSocket協議
- 3.5 MTQQ協議
- 內置http_server
- 內置websocket_server
- Swoole\Redis\Server
- 4 Swoole異步IO
- 4.1 AsyncIO
- 異步文件系統IO
- swoole_async_readfile
- swoole_async_writefile
- swoole_async_read
- swoole_async_write
- 5 swoole異步客戶端
- ws_client
- http_client
- mysql_client
- redis_client
- tcp_client
- http2_client
- 6 swoole協程
- Swoole\Coroutine\Http\Client
- Swoole\Coroutine\MySQL
- Swoole\Coroutine\Redis
- Coroutine\PostgreSQL
- Swoole\Coroutine\Client
- Swoole\Coroutine\Socket
- Swoole\Coroutine\Channel
- Coroutine
- Swoole\Coroutine::create
- Swoole\Coroutine::resume
- Swoole\Coroutine::suspend
- Swoole\Coroutine::sleep
- Coroutine::getaddrinfo
- Coroutine::gethostbyname
- swoole_async_dns_lookup_coro
- Swoole\Coroutine::getuid
- getDefer
- setDefer
- recv
- Coroutine::stats
- Coroutine::fread
- Coroutine::fget
- Coroutine::fwrite
- Coroutine::readFIle
- Coroutine::writeFIle
- Coroutine::exec
- 7 swoole_process
- process::construct
- process::start
- process::name
- process::signal
- process::setaffinity
- process::exit
- process::kill
- process::daemon
- process->exec
- process::wait
- process::alarm
- 8 swoole定時器
- swoole_timer_tick
- swoole_timer_after
- swoole_timer_clear
- 9 swoole_event
- swoole_event_add
- swoole_event_set
- swoole_event_del
- swoole_event_wait
- swoole_event_defer
- swoole_event_write
- swoole_event_exit
- swoole提供的function
- 常見問題
- 客戶端鏈接失敗原因
- 如何設置進程數
- 如何實現異步任務
- 如何選擇swoole三種模式
- php中哪些函數是阻塞的
- 是否可以共用1個redis或mysql連接
- 如何在回調函數中訪問外部的變量
- 為什么不要send完后立即close
- 不同的Server程序實例間如何通信
- MySQL的連接池、異步、斷線重連
- 在php-fpm或apache中使用swoole
- 學習Swoole需要掌握哪些基礎知識
- 在phpinfo中有在php-m中沒有
- 同步阻塞與異步非阻塞選擇
- CURL發送POST請求服務器端超時
- 附錄
- 預定義常量
- 內核參數調優
- php四種回調寫法
- 守護進程程序常用數據結構
- swoole生命周期
- swoole_server中內存管理機制
- 使用jemalloc優化swoole內存分配性能
- Reactor、Worker、Task的關系
- Manager進程
- Swoole的實現
- Reactor線程
- 安裝擴展
- swoole-worker手冊
- swoole相關開源項目
- 寫在后面的話
- 版本更新記錄
- 4.0