swoole 安装
用的是centOS
php安装目录:/usr/local/php
php.ini配置文件路径:/usr/local/php/etc/php.ini
1、安装swoole
cd /usr/local/src
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页面可以看到关于swoole的选项,说明安装成功。
搭建tcp 服务器
//创建服务器
$host = '0.0.0.0';
$port = 9501;
$serv = new swoole_server($host,$port) ;
/*
$host:127.0.0.1 本地ip 可以监听多个ip 使用0.0.0.0
$port:端口号
1024端口以下需要root权限
$mode : SWOOLE_PROCESS 多进程的方式
$socke_type:SWOOLE_SPCL_TCP
/
//使用
// bool $swoole_server->on(string $event,mixed $callback)
/*
$event:
connect: 当建立连接的时候 $serv 服务器信息 $fd:客户端信息
receive: 当接受到的数据$serv 服务器信息,$fd 客户端,$from_id ID,$data 数据
close:关闭连接
*/
$serv->on('connect',function($serv,$fd){
echo "连接成功"
});
$serv->on('receive',function($serv,$fd,$from_id,$data){
echo "接收到的数据";
var_dump($data); //打印接收到的数据
});
$serv->on('close',function($serv,$fd){
echo"连接关闭";
})
$serv->start();//启动服务
?>
上传到 服务器后
php index.php 启动
ps -ajft 查看进程来查看启动成功没
使用网络调试助手来进行调试查看tcp服务是否好用
UDP服务器创建
udp.php
$serv = new swoole_server("0.0.0.0",9502,SWOOLE_PROCESS,SWOOLE_SOCK_UDP)
//监听数据接收事件
/*
$serv:服务器信息
$data:数据,接收到的数据
$fd:客户端信息
*/
$serv->on('packet',function($serv,$data,$fd){
//发送数据到相应的客户端,反馈信息
$serv->sendto($fd['address'],$fd['port'],"Server: $data");
var_dump($fd);
}
);
$serv->start()
?>
web 服务器
//创建web服务器
$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");//设置返回头信息
$response->end("hello word".rand(100,999));
});
$serv->start();
?>
实现websocket
//创建webscork 服务器
$ws =new swoole_websocket_server
//on
//open 建立连接 $ws 服务器, $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 关闭连接
$ws->on('close',function($ws,$request){
echo "close\n";
})
$ws->start();
?>
webscork.html
//指的服务器webscort服务器
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("关闭")
}
webSocket.onmessage = function(evt){
console.log(data);
}
webSocket.onerror = function(evt,e){
console.log("error")
}
//循环执行定时器
swoole_time_tick(2000,function($timer_id){
echo "执行 $timer_id \n";
});
//单次执行
swoole_time_after(3000,function(){
echo "3 秒后执行"
})
?>
//task() 函数 投递异步任务
//on('事件',function(){}) 处理函数 执行异步函数
//finish()函数, 任务处理完成后结果
//异步TCP服务器
//创建TCP服务器
$serv = new swoole_server("0.0.0.0",9501);
//设置异步 进程工作数
$serv ->set(array('task_worker_num' =>4 ));
// 投递异步任务
$serv->on("receive",function($serv,$fd,$from_id,$data){
$task_id = $serv->tack($data);//获取异步ID
echo "异步ID: $task_id\n";
});
//处理异步任务
$serv -> on('task',functino($serv,$task_id,$from_id,$data){
echo "执行 异步ID:$task_id";
$serv-finish("$data->ok");
});
//处理结果
$serv ->on('finish',function($serv,$task_id,$data){
echo "执行完成";
})
$serv->start();
?>
//进程创建
/*
new swoole_process()
参数1: mixed $function 子进程创建成功后执行的函数
参数2: $redirect_stdin_stdout 重定向子进程的标准输入和输出。启用此选项后,在进程内echo将不是打印屏幕。而是写入到管道
读取键盘输入将变成从管道中读取。默认为阻塞读取
$create_pipe 是否创建管道。启用
$redirect_stdin_stdout后,此选项将忽略用户参数,强制为true,如果子进程内没有进程间通信,可以设置为false
*/
//创建进程
//进程对应的执行函数
function doProcess(swoole_process $worker){
echo "PID",$worker->pid,"\n";
sleep(10);
}
//创建进程
//创建多个进程
$process = new swoole_process("doProcess");
$pid = $process->start();
$process = new swoole_process("doProcess");
$pid = $process->start();
//等待结束
swoole_process::wait();
?>
//进程事件
//swoole_event_add()
/*参数1:int_$sock
int 文件描述
mixed $read callback 就是 stream_socket_client/fsockopen创建资源
sockets 就是sockets扩展中socket_create创建的资源,需要在编译时候加入
./configure --enable-sockets
*/
$workers = [];//进程数组
$worker_num =3;//创建进程的数量
//创建启动进程
for ($i = 0;$i
$process =new swoole_process('doProcess');//创建单独的新进程
$pid = $process->start();//启动进程,获取进程ID
$workers[$pid] = $process;// 存入进程数组
}
//创建进程执行函数
function doProcess(swoole_process $process){
$process->write("PID:$process->pid");//子进程写入信息
echo "写入信息: $process->pid $process->callback";
}
//添加进程事件 向每一个子进程添加需要执行的动作
foreach($workers as $process){
//添加
swoole_event_add($process->pipe,function($pipe) use($process){
$data = $process->read();//能否读取数据
echo "接受到:$data \n";
});
}
?>
//进程队列通信
$workers = [];//进程仓库
$worker_num = 2;//最大进程数
//批量创建进程
for($i = 0;$i
$process = new swoole_process('doProcess',false,false)//创建子进程完成
$process->useQuneue();//开启队列,类似于全局函数
$pid = $process->start();
$workers[$pid] = $process
}
//进程执行函数
function doProcess(swoole_process $process){
$recv = $process->pop();//8192
echo "从主进程获取到的数据:$recv \n";
sleep(5);
$process->exit(0);
}
//主进程 向子进程添加数据
foreach($workers as $pid =>$process){
$process->push("Hello 子进程 $pid \n")
}
//等待子进程结束回收资源
for($i=0;$i
$ret = swoole_process::wait();//等待执行完成
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子进程退出 $pid \n";
}
?>
//触发函数 异步执行 达到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);
?>
//创建锁对象
$lock = new swoole_lock(SWOOLE_MUTEX);//互斥锁
echo "创建互斥锁\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 "子进程退出";
?>
//dns查询
swoole_async_dns_lookup('www.baidu.com',function($host,$ip){
echo "$host,$ip";
})
?>
swoole 实现及时通信 服务器端
//服务器代码
//创建websocker 服务器
$ws =new swoole_websocket_server("0.0.0.0",9502);
//on 函数 open message close
//open情况
$ws->on('open',function($ws,$request){
echo "新用户 $request->fd 加入。\n";
$GLOBALS['fd'][$request->fd]['id'] =$request->fd;//设置用户ID
$GLOBALS['fd'][$request->fd]['name'] ='匿名用户';//设置用户名
});
//message 收发消息
$ws->on('message',function($ws,$request){
$msg =$GLOBALS['fd'][$request->fd]['name'].":".$request->data."\n";
if(strstr($request->data,"#name#")){
//用户设置昵称
$GLOBALS['fd'][$request->fd]['name']=str_replace("#name#",'',$request->data);
}else{ //进行用户信息发送
//发送到每一个客户端
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()
?>