# swoole_server函數列表
---
[TOC=2,3]
## **swoole_server::__construct**
**功能描述**:創建一個swoole_server資源對象
**函數原型**:
```php
// 類成員函數
public function swoole_server::__construct(string $host, int $port, int $mode = SWOOLE_PROCESS,int $sock_type = SWOOLE_SOCK_TCP);
```
**返回**:一個swoole_server對象
**參數說明**:
| 參數 | 說明 |
| -------- | -------- |
| string host | 監聽的IP地址 |
| int port | 監聽的端口號 |
| int mode | 運行模式 |
| int sock_type | 指定的socket類型 |
**說明**:
host、port、socket_type的詳細說明見[swoole_server::addlistener](#swoole_serveraddlistener)。<br>
mode指定了swoole_server的運行模式,共有如下三種:<br>
| mode | 類型 | 說明 |
| -------- | -------- | -------- |
| SWOOLE_BASE | Base模式 | 傳統的異步非阻塞Server。在Reactor內直接回調PHP的函數。如果回調函數中有阻塞操作會導致Server退化為同步模式。worker_num參數對與BASE模式仍然有效,swoole會啟動多個Reactor進程 |
| SWOOLE_THREAD | 線程模式(已廢棄)| 多線程Worker模式,Reactor線程來處理網絡事件輪詢,讀取數據。得到的請求交給Worker線程去處理。多線程模式比進程模式輕量一些,而且線程之間可以共享堆棧和資源。 訪問共享內存時會有同步問題,需要使用Swoole提供的鎖機制來保護數據。 |
| SWOOLE_PROCESS | 進程模式(默認) | Swoole提供了完善的進程管理、內存保護機制。 在業務邏輯非常復雜的情況下,也可以長期穩定運行,適合業務邏輯非常復雜的場景。 |
**樣例**:<br>
```php
$serv = new swoole_server("127.0.0.1" , 8888 , SWOOLE_PROCESS , SWOOLE_SOCK_TCP);
```
## **swoole_server::set**
**功能描述**:設置swoole_server運行時的各項參數<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::set(array $setting);
// 公共函數
function swoole_server_set(swoole_server $server, array $setting);
```
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| array setting | 配置選項數組,采用key-value形式 |
**說明**:<br>
該函數必須在[swoole_server::start](#swoole_serverstart)函數調用前調用。<br>
全部swoole_server的配置參數[點此查看](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md)<br>
**樣例**:<br>
```php
$serv->set(
array(
'worker_num' => 8,
'max_request' => 10000,
'max_conn' => 100000,
'dispatch_mode' => 2,
'debug_mode'=> 1,
'daemonize' => false,
)
);
```
## **swoole_server::on**
**功能描述**:綁定swoole_server的相關回調函數<br>
**函數原型**:<br>
```php
// 類成員函數
public function bool swoole_server->on(string $event, mixed $callback);
```
**返回**:設置成功返回true,否則返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| string event | 回調的名稱(大小寫不敏感) |
| mixed callback | 回調的PHP函數,可以是函數名的字符串,類靜態方法,對象方法數組,匿名函數 |
**說明**:<br>
該函數必須在[swoole_server::start](#swoole_serverstart)函數調用前調用。<br>
[swoole_server::on](#swoole_serveron)中事件名稱字符串不要加on。<br>
全部的回調函數列表[點此查看](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md)<br>
**樣例**:<br>
```php
$serv->on('connect', function ($serv, $fd){
echo "Client:Connect.\n";
});
$serv->on('receive', array( $myclass, 'onReceive' ) ); // onReceive是myclass的成員函數
```
## **swoole_server::addlistener**
**功能描述**:給swoole_server增加一個監聽的地址和端口<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::addlistener(string $host, int $port, $type = SWOOLE_SOCK_TCP);
// 公共函數
function swoole_server_addlisten(swoole_server $serv, string $host, int $port, $type = SWOOLE_SOCK_TCP);
```
別名swoole_server->listen
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| string host | 監聽的IP地址 |
| int port | 監聽的端口號 |
| int sock_type | 指定的socket類型 |
**說明**:
swoole支持如下socket類型:<br>
| sock_type | 說明 |
| -------- | -------- |
| SWOOLE_TCP/SWOOLE_SOCK_TCP | TCP IPv4 Socket |
| SWOOLE_TCP6/SWOOLE_SOCK_TCP6 | TCP IPv6 Socket |
| SWOOLE_UDP/SWOOLE_SOCK_UDP | UDP IPv4 Socket |
| SWOOLE_UDP6/SWOOLE_SOCK_UDP6 | UDP IPv4 Socket |
| SWOOLE_UNIX_DGRAM | Unix UDP Socket |
| SWOOLE_UNIX_STREAM | Unix TCP Socket |
> Unix Socket僅在1.7.1+后可用,此模式下**host**參數必須填寫可訪問的文件路徑,**port**參數忽略<br>
Unix Socket模式下,客戶端**fd**將不再是數字,而是一個文件路徑的字符串<br>
SWOOLE_TCP等是1.7.0+后提供的簡寫方式,與1.7.0前的SWOOLE_SOCK_TCP是等同的<br>
**樣例**:<br>
```php
$serv->addlistener("127.0.0.1", 9502, SWOOLE_SOCK_TCP);
$serv->addlistener("192.168.1.100", 9503, SWOOLE_SOCK_TCP);
$serv->addlistener("0.0.0.0", 9504, SWOOLE_SOCK_UDP);
$serv->addlistener("/var/run/myserv.sock", 0, SWOOLE_UNIX_STREAM);
swoole_server_addlisten($serv, "127.0.0.1", 9502, SWOOLE_SOCK_TCP);
```
## **swoole_server::addProcess**
**功能描述**:添加一個用戶自定義的工作進程。<br>
**函數原型**:<br>
```php
// 類成員函數
public function bool swoole_server->addProcess(swoole_process $process);
```
**返回**:無<br>
**參數說明**:<br>
* $process 為swoole_process對象,注意不需要執行start。在swoole_server啟動時會自動創建進程,并執行指定的子進程函數
* 創建的子進程可以調用$server對象提供的各個方法,如connection_list/connection_info/stats
* 在worker/task進程中可以調用$process提供的方法與子進程進行通信
* 在用戶自定義進程中可以調用$server->sendMessage與worker/task進程通信
**說明**:
>子進程會托管到Manager進程,如果發生致命錯誤,manager進程會重新創建一個
>子進程內不能使用swoole_server->task/taskwait接口
>此函數在swoole-1.7.9以上版本可用
**樣例**:<br>
```php
$server = new swoole_server('127.0.0.1', 9501);
$process = new swoole_process(function($process) use ($server) {
while (true) {
$msg = $process->read();
foreach($server->connections as $conn) {
$server->send($conn, $msg);
}
}
});
$server->addProcess($process);
$server->on('receive', function ($serv, $fd, $from_id, $data) use ($process) {
//群發收到的消息
$process->write($data);
});
$server->start();
```
## **swoole_server::start**
**功能描述**:啟動server,開始監聽所有TCP/UDP端口<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::start()
```
**返回**:啟動成功返回true,否則返回false<br>
**參數說明**:無<br>
**說明**:<br>
啟動成功后會創建worker_num+2個進程:Master進程+Manager進程+worker_num 個 Worker進程。<br>
另外。啟用task_worker會增加task_worker_num個Worker進程<br>
三種進程的說明如下:
| 進程類型 | 說明 |
| -------- | -------- |
| Master進程 | 主進程內有多個Reactor線程,基于epoll/kqueue進行網絡事件輪詢。收到數據后轉發到Worker進程去處理 |
| Manager進程 | 對所有Worker進程進行管理,Worker進程生命周期結束或者發生異常時自動回收,并創建新的Worker進程 |
| Worker進程 | 對收到的數據進行處理,包括協議解析和響應請求 |
**樣例**:
```php
$serv->start();
```
## **swoole_server::reload**
**功能描述**:重啟所有worker進程。<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::reload()
```
**返回**:調用成功返回true,否則返回false<br>
**參數說明**:無<br>
**說明**:<br>
調用后會向Manager發送一個SIGUSR1信號,平滑重啟全部的Worker進程(所謂平滑重啟,是指重啟動作會在Worker處理完正在執行的任務后發生,并不會中斷正在運行的任務。)<br>
小技巧:在[onWorkerStart](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#3onworkerstart)回調中require相應的php文件,當這些文件被修改后,只需要通過SIGUSR1信號即可實現服務器熱更新。<br>
1.7.7版本增加了僅重啟task_worker的功能。只需向服務器發送SIGUSR2即可<br>
**樣例**:
```php
$serv->reload();
```
## **swoole_server::stop**
**功能描述**:使當前worker進程停止運行,并立即觸發onWorkerStop回調函數。<br>
**函數原型**:<br>
```php
// 類成員函數
function swoole_server->stop(int $worker_id = -1, bool $waitEvent = false);
```
**返回**:調用成功返回true,否則返回false<br>
**參數說明**:無<br>
**說明**:<br>
* 使用此函數代替exit/die結束Worker進程的生命周期
* $waitEvent可以控制退出策略,默認為false表示立即退出,設置為true表示等待事件循環為空時再退出
* 如果要結束其他Worker進程,可以在stop里面加上worker_id作為參數或者使用swoole_process::kill($worker_pid)
* 設置$waitEvent = true后,底層會使用異步安全重啟策略。先通知Manager進程,重新啟動一個新的Worker來處理新的請求。當前舊的Worker會等待事件,直到事件循環為空或者超過max_wait_time后,退出進程,最大限度的保證異步事件的安全性。
**樣例**:
```php
$serv->shutdown();
```
## **swoole_server::shutdown**
**功能描述**:關閉服務器。<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::shutdown()
```
**返回**:調用成功返回true,否則返回false<br>
**參數說明**:無<br>
**說明**:<br>
此函數可以用在worker進程內,平滑關閉全部的Worker進程。<br>
也可向Master進程發送SIGTERM信號關閉服務器。<br>
**樣例**:
```php
$serv->shutdown();
```
## **swoole_server::tick**
**功能描述**:設置一個固定間隔的定時器<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server->tick(int $ms, callable $callback, mixed $user_param);
// 公共函數
function swoole_timer_tick(int $ms, callable $callback, mixed $user_param);
```
**返回**:設置成功返回true,否則返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int interval | 定時器的時間間隔,單位為毫秒ms |
| callback $callback | 定時器的回調函數,單位為毫秒ms |
**說明**:<br>
swoole定時器的最小顆粒是1毫秒,支持多個不同間隔的定時器。<br>
注意不能存在2個相同間隔時間的定時器。<br>
使用多個定時器時,其他定時器必須為最小定時器時間間隔的整數倍。<br>
該函數只能在onWorkerStart/onConnect/onReceive/onClose回調函數中調用。<br>
增加定時器后需要為Server設置[onTimer](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#8ontimer)回調函數,否則Server將無法啟動。<br>
**樣例**:
```php
function onReceive($server, $fd, $from_id, $data) {
$server->tick(1000, function() use ($server, $fd) {
$server->send($fd, "hello world");
});
}
```
## **swoole_server::clearTimer**
**功能描述**:刪除指定的定時器。<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::clearTimer(int $timer_id);
```
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int $timer_id | 定時器的id |
**說明**:<br>
刪除id為$timer_id的定時器
**樣例**:
```php
$serv->clearTimer(1000);
```
## **swoole_server::after**
**功能描述**:在指定的時間后執行函數<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::after(int $after_time_ms, mixed $callback_function, mixed params);
// 公共函數
function swoole_timer_after(int $after_time_ms, mixed $callback_function, mixed params);
```
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int after_time_ms | 指定時間,單位為毫秒ms |
| mixed callback_function | 指定的回調函數 |
| mixed params | 指定的回調函數的參數 |
**說明**:<br>
創建一個一次性定時器,在指定的after_time_ms時間后調用callback_funciton回調函數,執行完成后就會銷毀。<br>
callback_function函數的參數為指定的params<br>
需要swoole-1.7.7以上版本。<br>
**樣例**:
```php
$serv->after(1000, function( $params ){
echo "Do something\n";
} , "data" );
```
## **swoole_server::close**
**功能描述**:關閉客戶端連接<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::close(int $fd, int $from_id = 0);
```
**返回**:關閉成功返回true,失敗返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int fd | 指定關閉的fd |
| int from_id | fd來自于哪個Reactor(swoole-1.6以后已廢棄該參數) |
**說明**:<br>
調用close關閉連接后,連接并不會馬上關閉,因此不要在close之后立即寫清理邏輯,而是應該在[onClose](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#5onclose)回調中處理<br>
**樣例**:
```php
$serv->close( $fd );
```
## **swoole_server::send**
**功能描述**:向客戶端發送數據<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::send(int $fd, string $data, int $from_id = 0);
```
**返回**:發送成功返回true,失敗返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int fd | 指定發送的fd |
| string data | 發送的數據 |
| int from_id | fd來自于哪個Reactor |
**說明**:<br>
- data,發送的數據,最大不得超過2M。send操作具有原子性,多個進程同時調用send向同一個連接發送數據,不會發生數據混雜。
- 如果要發送超過2M的數據,建議將數據寫入臨時文件,然后通過sendfile接口直接發送文件
- UDP協議,send會直接在worker進程內發送數據包
- 向UDP客戶端發送數據,必須要傳入from_id
- 發送成功會返回true,如果連接已被關閉或發送失敗會返回false
- swoole-1.6以上版本不需要from_id
- UDP協議使用fd保存客戶端IP,from_id保存from_fd和port
- UDP協議如果是在onReceive后立即向客戶端發送數據,可以不傳from_id
**樣例**:
```php
$serv->send( $fd , "Hello World");
```
## **swoole_server::sendfile**
**功能描述**:發送文件到TCP客戶端連接<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::sendfile(int $fd, string $filename);
```
**返回**:發送成功返回true,失敗返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int fd | 指定發送的fd |
| string filename | 發送的文件名 |
**說明**:<br>
sendfile函數調用OS提供的sendfile系統調用,由操作系統直接讀取文件并寫入socket。sendfile只有2次內存拷貝,使用此函數可以降低發送大量文件時操作系統的CPU和內存占用。<br>
**樣例**:
```php
$serv->sendfile($fd, __DIR__.'/test.jpg');
```
## **swoole_server::sendMessage**
**功能描述**:獲取連接的信息<br>
**函數原型**:<br>
~~~
bool swoole_server->sendMessage(string $message, int $dst_worker_id);
~~~
**說明**
* $message為發送的消息數據內容,沒有長度限制,但超過8K時會啟動內存臨時文件
* $dst_worker_id為目標進程的ID,范圍是0 ~ (worker_num + task_worker_num - 1)
* 在Task進程內調用sendMessage是阻塞等待的,發送消息完成后返回
* 在Worker進程內調用sendMessage是異步的,消息會先存到發送隊列,可寫時向管道發送此消息
* 在User進程內調用sendMessage底層會自動判斷當前的進程是異步還是同步選擇不同的發送方式
>sendMessage接口在swoole-1.7.9以上版本可用
>MacOS/FreeBSD下超過2K就會使用臨時文件存儲
>使用sendMessage必須注冊onPipeMessage事件回調函數
**實例**
```php
$serv = new swoole_server("0.0.0.0", 9501);
$serv->set(array(
'worker_num' => 2,
'task_worker_num' => 2,
));
$serv->on('pipeMessage', function($serv, $src_worker_id, $data) {
echo "#{$serv->worker_id} message from #$src_worker_id: $data\n";
});
$serv->on('task', function ($serv, $task_id, $from_id, $data){
var_dump($task_id, $from_id, $data);
});
$serv->on('finish', function ($serv, $fd, $from_id){
});
$serv->on('receive', function (swoole_server $serv, $fd, $from_id, $data) {
if (trim($data) == 'task')
{
$serv->task("async task coming");
}
else
{
$worker_id = 1 - $serv->worker_id;
$serv->sendMessage("hello task process", $worker_id);
}
});
$serv->start();
```
## **swoole_server::exist**
**功能描述**:檢測fd對應的連接是否存在<br>
**函數原型**:<br>
~~~
bool function swoole_server->exist(int $fd)
~~~
**返回**:如果fd存在,返回true,連接不存在返回false<br>
**說明**
>此接口是基于共享內存計算,沒有任何IO操作
>swoole_server->exist在1.7.18以上版本可用
## **swoole_server::connection_info**
**功能描述**:獲取連接的信息<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::connection_info(int $fd, int $from_id = 0);
```
**返回**:如果fd存在,返回一個數組,連接不存在或已關閉返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int fd | 指定發送的fd |
| int from_id | 來自于哪個Reactor |
**說明**:<br>
UDP socket調用該參數時必須傳入from_id.<br>
返回的結果如下:
| 名稱 | 說明 |
| -------- | -------- |
| int from_id | 來自于哪個Reactor |
| int from_fd | 來自哪個Server Socket |
| int from_port | 來自哪個Server端口 |
| int remote_port | 客戶端連接的端口 |
| string remote_ip | 客戶端連接的ip |
| int connect_time | 連接到Server的時間,單位秒 |
| int last_time | 最后一次發送數據的時間,單位秒 |
sendfile函數調用OS提供的sendfile系統調用,由操作系統直接讀取文件并寫入socket。sendfile只有2次內存拷貝,使用此函數可以降低發送大量文件時操作系統的CPU和內存占用。<br>
**樣例**:
```php
$fdinfo = $serv->connection_info($fd);
$udp_client = $serv->connection_info($fd, $from_id);
```
## **swoole_server::connection_list**
**功能描述**:遍歷當前Server的全部客戶端連接<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::connection_list(int $start_fd = 0, int $pagesize = 10);
```
**返回**:調用成功將返回一個數字索引數組,元素是取到的fd。數組會按從小到大排序。最后一個fd作為新的start_fd再次嘗試獲取。<br>
調用失敗返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| int start_fd | 起始fd |
| int pagesize | 每頁取多少條,最大不得超過100. |
**說明**:<br>
connection_list僅可用于TCP,UDP服務器需要自行保存客戶端信息<br>
**樣例**:
```php
$start_fd = 0;
while(true)
{
$conn_list = $serv->connection_list($start_fd, 10);
if($conn_list===false)
{
echo "finish\n";
break;
}
$start_fd = end($conn_list);
var_dump($conn_list);
foreach($conn_list as $fd)
{
$serv->send($fd, "broadcast");
}
}
```
## **swoole_server::stats**
**功能描述**:獲取當前Server的活動TCP連接數,啟動時間,accpet/close的總次數等信息。<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server->stats();
```
**返回**:結果數組<br>
**參數說明**:無<br>
**說明**:<br>
stats方法在1.7.5+后可用<br>
| 名稱 | 說明 |
| -------- | -------- |
| int start_time | 啟動時間 |
| int connection_num | 當前的連接數 |
| int accept_count | accept總次數 |
| int close_count | close連接的總數 |
**樣例**:
```php
$status = $serv->stats();
```
## **swoole_server::task**
**功能描述**:投遞一個異步任務到task_worker池中<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::task(string $data, int $dst_worker_id = -1);
```
**返回**:調用成功返回task_worker_id,失敗返回false<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| string data | task數據 |
| int dst_worker_id | 指定投遞給哪個task進程,默認隨機投遞 |
**說明**:<br>
此功能用于將慢速的任務異步地去執行,調用task函數會立即返回,Worker進程可以繼續處理新的請求。<br>
函數會返回一個`$task_id`數字,表示此任務的ID<br>
任務完成后,可以通過return(低于swoole-1.7.2版本使用[finish](#swoole_serverfinish)函數)將結果通過[onFinish](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#7onfinish)回調返回給Worker進程。<br>
發送的data必須為字符串,如果是數組或對象,請在業務代碼中進行serialize處理,并在[onTask](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#6ontask)/[onFinish](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#7onfinish)中進行unserialize。<br>
data可以為二進制數據,最大長度為**8K**(超過8K可以使用臨時文件共享)。字符串可以使用gzip進行壓縮。<br>
使用task必須為Server設置[onTask](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#6ontask)和[onFinish](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#7onfinish)回調,并指定[task_worker_num](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/01.%E9%85%8D%E7%BD%AE%E9%80%89%E9%A1%B9.md#6task_worker_num)配置參數。
**樣例**:
```php
$task_id = $serv->task("some data");
```
## **swoole_server::taskwait**
**功能描述**:投遞一個同步任務到task_worker池中<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::taskwait(string $task_data, float $timeout = 0.5, int $dst_worker_id = -1);
```
**返回**:task執行的結果<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| string data | task數據 |
| float timeout | 超時時間 |
| int dst_worker_id | 指定投遞給哪個task進程,默認隨機投遞 |
**說明**:<br>
taskwait與task方法作用相同,用于投遞一個異步的任務到task進程池去執行。與task不同的是taskwait是阻塞等待的,直到任務完成或者超時返回。<br>
任務完成后,可以通過return直接返回結果<br>
**樣例**:
```php
$task_id = $serv->taskwait("some data", 30);
```
## **swoole_server::taskWaitMulti**
**功能描述**:并發執行多個Task
**函數原型**:<br>
~~~
array swoole_server->taskWaitMulti(array $tasks, double $timeout = 0.5);
~~~
* $tasks 必須為數字索引數組,不支持關聯索引數組,底層會遍歷$tasks將任務逐個投遞到Task進程
* $timeout 為浮點型,單位為秒,默認為0.5
* 任務完成或超時,返回結果數組。結果數組中每個任務結果的順序與$tasks對應,如:$tasks[2]對應的結果為$result[2]
* 某個任務執行超時不會影響其他任務,返回的結果數據中將不包含超時的任務
>taskWaitMulti接口在1.8.8或更高版本可用
>最大并發任務不得超過1024
**使用實例**
```php
$tasks[] = mt_rand(1000, 9999); //任務1
$tasks[] = mt_rand(1000, 9999); //任務2
$tasks[] = mt_rand(1000, 9999); //任務3
var_dump($tasks);
//等待所有Task結果返回,超時為10s
$results = $serv->taskWaitMulti($tasks, 10.0);
if (!isset($results[0])) {
echo "任務1執行超時了\n";
}
if (isset($results[1])) {
echo "任務2的執行結果為{$results[1]}\n";
}
if (isset($results[2])) {
echo "任務3的執行結果為{$results[2]}\n";
}
```
## **swoole_server::taskCo**
**功能描述**:并發執行Task并進行協程調度。僅用于2.0版本。
**函數原型**:<br>
~~~
function swoole_server->taskCo(array $tasks, float $timeout = 0.5) : array;
~~~
* $tasks任務列表,必須為數組。底層會遍歷數組,將每個元素作為task投遞到Task進程池
* $timeout超時時間,默認為0.5秒,當規定的時間內任務沒有全部完成,立即中止并返回結果
* 任務完成或超時,返回結果數組。結果數組中每個任務結果的順序與$tasks對應,如:$tasks[2]對應的結果為$result[2]
* 某個任務執行失敗或超時,對應的結果數組項為false,如:$tasks[2]失敗了,那么$result[2]的值為false
>最大并發任務不得超過1024
>taskCo在2.0.9或更高版本可用
**調度過程**
$tasks列表中的每個任務會隨機投遞到一個Task工作進程,投遞完畢后,yield讓出當前協程,并設置一個$timeout秒的定時器
在onFinish中收集對應的任務結果,保存到結果數組中。判斷是否所有任務都返回了結果,如果為否,繼續等待。如果為是,進行resume恢復對應協程的運行,并清除超時定時器
在規定的時間內任務沒有全部完成,定時器先觸發,底層清除等待狀態。將未完成的任務結果標記為false,立即resume對應協程
**使用示例**
~~~
<?php
$server = new Swoole\Http\Server("127.0.0.1", 9502, SWOOLE_BASE);
$server->set([
'worker_num' => 1,
'task_worker_num' => 2,
]);
$server->on('Task', function (swoole_server $serv, $task_id, $worker_id, $data) {
echo "#{$serv->worker_id}\tonTask: worker_id={$worker_id}, task_id=$task_id\n";
if ($serv->worker_id == 1) {
sleep(1);
}
return $data;
});
$server->on('Request', function ($request, $response) use ($server)
{
$tasks[0] = "hello world";
$tasks[1] = ['data' => 1234, 'code' => 200];
$result = $server->taskCo($tasks, 0.5);
$response->end('Test End, Result: '.var_export($result, true));
});
$server->start();
~~~
## **swoole_server::finish**
**功能描述**:傳遞Task結果數據給worker進程<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::finish(string $task_data);
```
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| string data | 結果數據 |
**說明**:<br>
使用swoole_server::finish函數必須為Server設置[onFinish](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#7onfinish)回調函數。此函數只可用于Task Worker進程的[onTask](https://github.com/LinkedDestiny/swoole-doc/blob/master/doc/02.%E4%BA%8B%E4%BB%B6%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0.md#6ontask)回調中<br>
swoole_server::finish是可選的。如果Worker進程不關心任務執行的結果,可以不調用此函數<br>
此函數在swoole-1.7.2以上版本已廢棄,使用return代替。<br>
**樣例**:
```php
$serv->finish("result data");
```
## **swoole_server::heartbeat**
**功能描述**:進行心跳檢測<br>
**函數原型**:<br>
```php
// 類成員函數
public function swoole_server::heartbeat(bool $if_close_connection = true);
```
**返回**:無<br>
**參數說明**:<br>
| 參數 | 說明 |
| -------- | -------- |
| bool if_close_connection | 是否關閉超時的連接,默認為true |
**說明**:<br>
該函數會主動發起一次檢測,遍歷全部連接,根據設置的[heartbeat_check_interval](server/set.md)和[heartbeat_idle_time](server/set.md)參數,找到那些處于idle閑置狀態的連接<br>
swoole默認會直接關閉這些連接,heartbeat會返回這些連接的fd<br>
如果if_close_connection為false,則heartbeat會返回這些idle連接的fd,但不會關閉這些連接<br>
if_close_connection參數 在swoole-1.7.4以上版本可用<br>
**樣例**:
```php
$serv->heartbeat();
```
## **swoole_server::getSocket**
**功能描述**:調用此方法可以得到底層的socket句柄,返回的對象為sockets資源句柄。
>此方法需要依賴PHP的sockets擴展,并且編譯swoole時需要開啟--enable-sockets選項
使用socket_set_option函數可以設置更底層的一些socket參數。
~~~
$socket = $server->getSocket();
if (!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo 'Unable to set option on socket: '. socket_strerror(socket_last_error()) . PHP_EOL;
}
~~~
**監聽端口**
使用listen方法增加的端口,可以使用Swoole\Server\Port對象提供的getSocket方法。
~~~
$port = $server->listen('127.0.0.1', 9502, SWOOLE_SOCK_TCP);
$socket = $port->getSocket();
~~~
**支持組播**
使用socket_set_option設置MCAST_JOIN_GROUP參數可以將Socket加入組播,監聽網絡組播數據包。
~~~
$server = new swoole_server('0.0.0.0', 9905, SWOOLE_BASE, SWOOLE_SOCK_UDP);
$server->set(['worker_num' => 1]);
$socket = $server->getSocket();
$ret = socket_set_option(
$socket,
IPPROTO_IP,
MCAST_JOIN_GROUP,
array('group' => '224.10.20.30', 'interface' => 'eth0')
);
if ($ret === false)
{
throw new RuntimeException('Unable to join multicast group');
}
$server->on('Packet', function (swoole_server $serv, $data, $addr)
{
$serv->sendto($addr['address'], $addr['port'], "Swoole: $data");
var_dump( $addr, strlen($data));
});
$server->start();
~~~
* group 表示組播地址
* interface 表示網絡接口的名稱,可以為數字或字符串,如eth0、wlan0
## **swoole_server::protect**
**功能描述**:設置客戶端連接為保護狀態,不被心跳線程切斷。
**函數原型**:
~~~
function swoole_server->protect(int $fd, bool $value = 1);
~~~
* $fd 要設置保護狀態的客戶端連接fd
* $value 設置的狀態,true表示保護狀態,false表示不保護
- 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