環(huán)境說明: 系統(tǒng):Ubuntu14.04 (安裝教程包括CentOS6.5)
PHP版本:PHP-5.5.10
swoole版本:1.7.7-stable
在實(shí)際運(yùn)用場景中,服務(wù)器可能需要監(jiān)聽不同host下的不同端口。比如,一個(gè)應(yīng)用服務(wù)器,可能需要監(jiān)聽外網(wǎng)的服務(wù)端口,同時(shí)也需要監(jiān)聽內(nèi)網(wǎng)的管理端口。在Swoole中,可以輕松的實(shí)現(xiàn)這樣的功能。 Swoole提供了addlistener函數(shù)用于給服務(wù)器添加一個(gè)需要監(jiān)聽的host及port,并指定對應(yīng)的Socket類型(TCP,UDP,Unix Socket以及對應(yīng)的IPv4和IPv6版本)。 代碼如下:
$serv = new swoole_server("192.168.1.1", 9501); // 監(jiān)聽外網(wǎng)的9501端口
$serv->addlistener("127.0.0.1", 9502 , SWOOLE_TCP); // 監(jiān)聽本地的9502端口
$serv->start(); // addlistener必須在start前調(diào)用
此時(shí),swoole_server就會(huì)同時(shí)監(jiān)聽兩個(gè)host下的兩個(gè)端口。這里要注意的是,來自兩個(gè)端口的數(shù)據(jù)會(huì)在同一個(gè)onReceive中獲取到,這時(shí)就要用到swoole的另一個(gè)成員函數(shù)connection_info,通過這個(gè)函數(shù)獲取到fd的from_port,就可以判定消息的類型。
$info = $serv->connection_info($fd, $from_id);
//來自9502的內(nèi)網(wǎng)管理端口
if($info['from_port'] == 9502) {
$serv->send($fd, "welcome admin\n");
}
//來自外網(wǎng)
else {
$serv->send($fd, 'Swoole: '.$data);
}
所謂熱重啟,就是當(dāng)服務(wù)器相關(guān)代碼有所變動(dòng)之后,無需停止服務(wù),而是在服務(wù)器仍然運(yùn)行的狀態(tài)下更新文件。Swoole通過內(nèi)置的reload函數(shù)以及兩個(gè)自定義信號(hào)量實(shí)現(xiàn)了這一功能。 首先我講解一下Swoole可用的三個(gè)信號(hào):SIGTERM,SIGUSR1,SIGUSR2。SIGTERM用于停止服務(wù)器,SIGUSR1用于重啟全部的Worker進(jìn)程,SIGUSR2用于重啟全部的Task Worker進(jìn)程。 那要如何實(shí)現(xiàn)熱更新代碼文件呢?Swoole的回調(diào)函數(shù)中有這個(gè)一個(gè)回調(diào)onWorkerStart;該回調(diào)會(huì)在Worker進(jìn)程啟動(dòng)時(shí)被調(diào)用。因此,當(dāng)swoole_server收到SIGUSR1信號(hào)并重啟全部Worker進(jìn)程后,onWorkerStart就會(huì)被調(diào)用。如果在onWorkerStart中require全部的代碼文件,每次onWorkerStart后都會(huì)重新require一次php文件,這樣就能實(shí)現(xiàn)代碼文件的熱更新。 來看下代碼實(shí)現(xiàn):
public function onStart( $serv ) {
cli_set_process_title("reload_master");
}
public function onWorkerStart( $serv , $worker_id) {
require_once "reload_page.php";
Test(); // reload_page.php中定義的一個(gè)函數(shù)
}
首先,在onStart回調(diào)函數(shù)中通過php的cli_set_process_title函數(shù)設(shè)置進(jìn)程名。 在onWorkerStart中,require相關(guān)的php文件。 然后,新建一個(gè)reload.sh文件,輸入如下內(nèi)容:
echo "Reloading..."
cmd=$(pidof reload_master)
kill -USR1 "$cmd"
echo "Reloaded"
這樣,就可以通過執(zhí)行這個(gè)腳本重啟服務(wù)器了。?點(diǎn)此查看完整源碼
在swoole-1.7.7stable版本中,Timer新增了一個(gè)函數(shù)after。該函數(shù)的作用是在指定的時(shí)間間隔后執(zhí)行回調(diào)函數(shù),并且只執(zhí)行一次。 這個(gè)函數(shù)可以彌補(bǔ)Timer本身做不到或者做起來很難的一些定時(shí)工作。 代碼如下:
$serv->after( 1000 , array($this, 'onAfter') , $str );
這里指定在1000ms后,執(zhí)行onAfter回調(diào)函數(shù),函數(shù)參數(shù)為$str。 舉個(gè)例子,比如服務(wù)器要求在收到某個(gè)請求后,在30S后向所有用戶發(fā)起推送。這樣的需求就可以直接用after函數(shù)來實(shí)現(xiàn)。?點(diǎn)此查看完整源碼
未完成
更多建議: