swoole 安裝
用的是centOS
php安裝目錄:/usr/local/php
php.ini配置文件路徑:/usr/local/php/etc/php.ini
1扮饶、安裝swoole
cd /usr/local/src
wget https://github.com/swoole/swoole-src/archive/v1.9.1-stable.tar.gz
tar zxvf v1.9.1-stable.tar.gz
cd swoole-src-1.9.1-stable
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make install
2凉夯、配置php支持swoole
vi /usr/local/php/etc/php.ini
添加
extension=swoole.so
3货葬、重啟php-fpm
service php-fpm restart
在phpinfo頁面可以看到關(guān)于swoole的選項,說明安裝成功劲够。
搭建tcp 服務(wù)器
<?php
//創(chuàng)建服務(wù)器
$host = '0.0.0.0';
$port = 9501;
$serv = new swoole_server($host,$port) ;
/*
- $host:127.0.0.1 本地ip 可以監(jiān)聽多個ip 使用0.0.0.0
- $port:端口號
- 1024端口以下需要root權(quán)限
- $mode : SWOOLE_PROCESS 多進程的方式
- $socke_type:SWOOLE_SPCL_TCP
/
//使用
// bool $swoole_server->on(string $event,mixed $callback)
/*
- $event:
- connect: 當(dāng)建立連接的時候 $serv 服務(wù)器信息 $fd:客戶端信息
- receive: 當(dāng)接受到的數(shù)據(jù)$serv 服務(wù)器信息,$fd 客戶端,$from_id ID,$data 數(shù)據(jù)
- close:關(guān)閉連接
*/
$serv->on('connect',function($serv,$fd){
echo "連接成功"
});
$serv->on('receive',function($serv,$fd,$from_id,$data){
echo "接收到的數(shù)據(jù)";
var_dump($data); //打印接收到的數(shù)據(jù)
});
$serv->on('close',function($serv,$fd){
echo"連接關(guān)閉";
})
$serv->start();//啟動服務(wù)
?>
上傳到 服務(wù)器后
php index.php 啟動
ps -ajft 查看進程來查看啟動成功沒
使用網(wǎng)絡(luò)調(diào)試助手來進行調(diào)試查看tcp服務(wù)是否好用
UDP服務(wù)器創(chuàng)建
udp.php
<?php
$serv = new swoole_server("0.0.0.0",9502,SWOOLE_PROCESS,SWOOLE_SOCK_UDP)
//監(jiān)聽數(shù)據(jù)接收事件
/*
$serv:服務(wù)器信息
$data:數(shù)據(jù),接收到的數(shù)據(jù)
-
$fd:客戶端信息
*/
$serv->on('packet',function($serv,$data,$fd){//發(fā)送數(shù)據(jù)到相應(yīng)的客戶端休傍,反饋信息
$serv->sendto($fd['address'],$fd['port'],"Server: $data");
var_dump($fd);
}
);
$serv->start()
?>
web 服務(wù)器
<?php
//創(chuàng)建web服務(wù)器
$serv = new swoole_http_server("0.0.0.0",9501);
// 獲取請求
/*
- $request:請求信息
- $response:返回信息
*/
$serv->on('request',function($request,$response){
var_dump($request);
$response->header("Content-Type","text/html;charset=utf-8");//設(shè)置返回頭信息
$response->end("hello word".rand(100,999));
});
$serv->start();
?>
實現(xiàn)websocket
<?php
//創(chuàng)建webscork 服務(wù)器
$ws =new swoole_websocket_server
//on
//open 建立連接 $ws 服務(wù)器, $request:客戶端信息
$ws ->on('open',function($ws,$request){
var_dump($request);
$ws->push($request->fd,"welcome \n");
})
//message 接收信息
$ws ->on('message',function($ws,$request){
echo "Message: $request->data";
$ws->push($request->fd,"get it message");
});
//close 關(guān)閉連接
$ws->on('close',function($ws,$request){
echo "close\n";
})
$ws->start();
?>
webscork.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//指的服務(wù)器webscort服務(wù)器
var wsServer="ws://192.168.0.1:9501;"
var webSocket = new WebSocket(wsServer);
webSocket.onopen = function(evt){
console.log("連接成功");
}
webSocket.onclose = function(evt){
console.log("關(guān)閉")
}
webSocket.onmessage = function(evt){
console.log(data);
}
webSocket.onerror = function(evt,e){
console.log("error")
}
</script>
</body>
</html>
<?php
//循環(huán)執(zhí)行定時器
swoole_time_tick(2000,function($timer_id){
echo "執(zhí)行 $timer_id \n";
});
//單次執(zhí)行
swoole_time_after(3000,function(){
echo "3 秒后執(zhí)行"
})
?>
<?php
//task() 函數(shù) 投遞異步任務(wù)
//on('事件',function(){}) 處理函數(shù) 執(zhí)行異步函數(shù)
//finish()函數(shù), 任務(wù)處理完成后結(jié)果
//異步TCP服務(wù)器
//創(chuàng)建TCP服務(wù)器
$serv = new swoole_server("0.0.0.0",9501);
//設(shè)置異步 進程工作數(shù)
$serv ->set(array('task_worker_num' =>4 ));
// 投遞異步任務(wù)
$serv->on("receive",function($serv,$fd,$from_id,$data){
$task_id = $serv->tack($data);//獲取異步ID
echo "異步ID: $task_id\n";
});
//處理異步任務(wù)
$serv -> on('task',functino($serv,$task_id,$from_id,$data){
echo "執(zhí)行 異步ID:$task_id";
$serv-finish("$data->ok");
});
//處理結(jié)果
$serv ->on('finish',function($serv,$task_id,$data){
echo "執(zhí)行完成";
})
$serv->start();
?>
<?php
//進程創(chuàng)建
/*
- new swoole_process()
- 參數(shù)1: mixed $function 子進程創(chuàng)建成功后執(zhí)行的函數(shù)
- 參數(shù)2: $redirect_stdin_stdout 重定向子進程的標(biāo)準(zhǔn)輸入和輸出征绎。啟用此選項后,在進程內(nèi)echo將不是打印屏幕。而是寫入到管道
- 讀取鍵盤輸入將變成從管道中讀取人柿。默認(rèn)為阻塞讀取
- $create_pipe 是否創(chuàng)建管道柴墩。啟用
- $redirect_stdin_stdout后,此選項將忽略用戶參數(shù),強制為true,如果子進程內(nèi)沒有進程間通信凫岖,可以設(shè)置為false
- */
//創(chuàng)建進程
//進程對應(yīng)的執(zhí)行函數(shù)
function doProcess(swoole_process $worker){
echo "PID",$worker->pid,"\n";
sleep(10);
}
//創(chuàng)建進程
//創(chuàng)建多個進程
$process = new swoole_process("doProcess");
$pid = $process->start();
$process = new swoole_process("doProcess");
$pid = $process->start();
//等待結(jié)束
swoole_process::wait();
?>
<?php
//進程事件
//swoole_event_add()
/*參數(shù)1:int_$sock
- int 文件描述
- mixed $read callback 就是 stream_socket_client/fsockopen創(chuàng)建資源
- sockets 就是sockets擴展中socket_create創(chuàng)建的資源江咳,需要在編譯時候加入
- ./configure --enable-sockets
- */
$workers = [];//進程數(shù)組
$worker_num =3;//創(chuàng)建進程的數(shù)量
//創(chuàng)建啟動進程
for ($i = 0;$i<$worker_num;$i++){
$process =new swoole_process('doProcess');//創(chuàng)建單獨的新進程
$pid = $process->start();//啟動進程,獲取進程ID
$workers[$pid] = $process哥放;// 存入進程數(shù)組
}
//創(chuàng)建進程執(zhí)行函數(shù)
function doProcess(swoole_process $process){
$process->write("PID:$process->pid");//子進程寫入信息
echo "寫入信息: $process->pid $process->callback";
}
//添加進程事件 向每一個子進程添加需要執(zhí)行的動作
foreach($workers as $process){
//添加
swoole_event_add($process->pipe,function($pipe) use($process){
$data = $process->read();//能否讀取數(shù)據(jù)
echo "接受到:$data \n";
});
}
?>
<?php
//進程隊列通信
$workers = [];//進程倉庫
$worker_num = 2;//最大進程數(shù)
//批量創(chuàng)建進程
for($i = 0;$i<$worker_num;$i++){
$process = new swoole_process('doProcess',false,false)//創(chuàng)建子進程完成
$process->useQuneue();//開啟隊列歼指,類似于全局函數(shù)
$pid = $process->start();
$workers[$pid] = $process
}
//進程執(zhí)行函數(shù)
function doProcess(swoole_process $process){
$recv = $process->pop();//8192
echo "從主進程獲取到的數(shù)據(jù):$recv \n";
sleep(5);
$process->exit(0);
}
//主進程 向子進程添加數(shù)據(jù)
foreach($workers as $pid =>$process){
$process->push("Hello 子進程 $pid \n")
}
//等待子進程結(jié)束回收資源
for($i=0;$i<$worker_num;$i++){
$ret = swoole_process::wait();//等待執(zhí)行完成
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子進程退出 $pid \n";
}
?>
<?php
//觸發(fā)函數(shù) 異步執(zhí)行 達(dá)到10次停止
swoole_process::signal(SIGALRM,function(){
static $i = 0;
echo "$i \n";
$i++;
if($i>10){
swoole_process::alarm(-1); //清除定時器
}
});
//定時器
swoole_process::alarm(100 *1000);
?>
<?php
//創(chuàng)建鎖對象
$lock = new swoole_lock(SWOOLE_MUTEX);//互斥鎖
echo "創(chuàng)建互斥鎖\n";
$lock->lock();//開始鎖定 主進程
if(pcntl_fork()>0){
sleep(1);
$lock->unlock();//解鎖
}else{
echo "子進程 等待鎖\n";
$lock->lock();//上鎖
echo "子進程 獲取所";
$lock->unlock();//釋放鎖
exit("子進程退出");
}
echo "主進程 釋放鎖";
unset($lock);
sleep(1);
echo "子進程退出";
?>
<?php
//dns查詢
swoole_async_dns_lookup('www.baidu.com',function($host,$ip){
echo "$host,$ip";
})
?>
swoole 實現(xiàn)及時通信 服務(wù)器端
<?php
//服務(wù)器代碼
//創(chuàng)建websocker 服務(wù)器
$ws =new swoole_websocket_server("0.0.0.0",9502);
//on 函數(shù) open message close
//open情況
$ws->on('open',function($ws,$request){
echo "新用戶 $request->fd 加入。\n";
$GLOBALS['fd'][$request->fd]['id'] =$request->fd;//設(shè)置用戶ID
$GLOBALS['fd'][$request->fd]['name'] ='匿名用戶';//設(shè)置用戶名
});
//message 收發(fā)消息
$ws->on('message',function($ws,$request){
$msg =$GLOBALS['fd'][$request->fd]['name'].":".$request->data."\n";
if(strstr($request->data,"#name#")){
//用戶設(shè)置昵稱
$GLOBALS['fd'][$request->fd]['name']=str_replace("#name#",'',$request->data);
}else{ //進行用戶信息發(fā)送
//發(fā)送到每一個客戶端
foreach ($GLOBALS['fd'] as $i){
$ws->push($i['id'],$msg);
}
}
});
//close
$ws->on('close',function($ws,$request){
echo "客戶端-{$request} 斷開連接\n";
unset($GLOBALS['fd'][$request]);//清除連接倉庫
});
$ws->start()
?>