# 多端口監聽
---
## 多端口監聽
在實際運用場景中,服務器可能需要監聽不同host下的不同端口。比如,一個應用服務器,可能需要監聽外網的服務端口,同時也需要監聽內網的管理端口。在Swoole中,可以輕松的實現這樣的功能。 Swoole提供了addlistener函數用于給服務器添加一個需要監聽的host及port,并指定對應的Socket類型(TCP,UDP,Unix Socket以及對應的IPv4和IPv6版本)。 代碼如下:
```php
$serv = new swoole_server("192.168.1.1", 9501); // 監聽外網的9501端口
$serv->addlistener("127.0.0.1", 9502 , SWOOLE_TCP); // 監聽本地的9502端口
$serv->start(); // addlistener必須在start前調用
```
此時,swoole_server就會同時監聽兩個host下的兩個端口。這里要注意的是,來自兩個端口的數據會在同一個`onReceive`回調函數中獲取到,這時就要用到swoole的另一個成員函數connection_info,通過這個函數獲取到fd的from_port,就可以判定消息的類型。
```php
$info = $serv->connection_info($fd, $from_id);
//來自9502的內網管理端口
if($info['from_port'] == 9502) {
$serv->send($fd, "welcome admin\n");
}
//來自外網
else {
$serv->send($fd, 'Swoole: '.$data);
}
```
## 多端口混合協議接聽
通過上面的實例可以看到,使用上面的方法進行多端口監聽有諸多的局限性:協議單一,回調函數無法區分等。在實際應用中,我們往往希望服務能夠同時監聽兩個端口,并且兩個端口分別采用不同的協議,比如一個端口采用RPC協議提供服務,另一個端口提供Http協議用于Web管理頁面。
因此,Swoole從1.8.0版本開始提供了一套全新的多端口監聽方式。在1.8.0以后的版本,Server可以監聽多個端口,每個端口都可以設置不同的協議處理方式(set)和回調函數(on)
開始監聽新端口的代碼如下:
```php
$port1 = $server->listen("127.0.0.1", 9501, SWOOLE_SOCK_TCP);
$port2 = $server->listen("127.0.0.1", 9502, SWOOLE_SOCK_UDP);
$port3 = $server->listen("127.0.0.1", 9503, SWOOLE_SOCK_TCP | SWOOLE_SSL);
```
可以看到,新添加的監聽端口可以設置多種屬性,監聽的IP,端口號,TCP或者UDP,是否需要SSL加密。
除此之外,每個新建立的Port對象還可以分別設置配置選項,如下所示:
```php
$port1->set( // 開啟固定包頭協議
'open_length_check' => true,
'package_length_type' => 'N',
'package_length_offset' => 0,
'package_max_length' => 800000,
);
$port3->set( // 開啟EOF協議并設置SSL文件
'open_eof_split' => true,
'package_eof' => "\r\n",
'ssl_cert_file' => 'ssl.cert',
'ssl_key_file' => 'ssl.key',
);
```
除了協議不同,每個Port還可以設置自己獨有的回調函數,由此避免了在同一個回調函數里針對數據來源進行判定的問題。
```php
$port1->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, 'Swoole: '.$data);
$serv->close($fd);
});
$port3->on('receive', function ($serv, $fd, $from_id, $data) {
echo "Hello {$fd} : {$data}\n";
});
```
### 注意事項
* 未設置協議處理選項的監聽端口,默認使用無協議模式
* 未設置回調函數的監聽端口,使用$server對象的回調函數
* 監聽端口返回的對象類型為swoole_server_port
* 不同監聽端口的回調函數,仍然是相同的Worker進程空間內執行
* 主服務器是WebSocket或Http協議,新監聽的TCP端口默認會繼承主Server的協議設置。必須單獨調用`set`方法設置新的協議才會啟用新協議
- 序章
- 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支持
- 3 Swoole協議
- 3.1 EOF協議
- 3.2 固定包頭協議
- 3.3 Http協議
- 3.4 WebSocket協議
- 3.5 MTQQ協議
- 4 Swoole客戶端
- 4.1 Client
- 4.2 異步Http客戶端
- 4.3 異步WebSocket客戶端
- 4.4 異步MySQL客戶端
- 4.5 異步Redis客戶端
- 5 Swoole異步IO
- 5.1 AsyncIO
- 5.2 EventLoop
- 6 Swoole使用
- 7 框架應用
- 7.1 ZPHP
- 7.2 TSF
- 7.3 Hprose
- 7.4 Dora-rpc
- 8 已有框架支持
- 8.1 Yaf
- 8.2 Phalcon
- 8.3 Thinkphp
- 9 項目實戰
- 附錄*配置選項
- 附錄*回調函數
- 附錄*屬性列表
- 附錄*函數列表