centos 7.6 安装swoole

【官方手册】https://linkeddestiny.gitbooks.io/easy-swoole/content/book/chapter01/install.html
【官网地址】https://wiki.swoole.com/wiki/index/prid-1#entry_h2_2

开发工具

Swoole官方QQ群: 705119448

安装环境

*   centos 7.2
*   php-7.0 或更高版本
*   gcc-4.8 或更高版本
安装依赖,安装前要检查是否已经安装这些依赖
gcc  
pcre   (centos系统可以执行命令:yum install pcre-devel)
autoconf  
make #安装前要确保已经安装了,gcc -v 查看版本信息 不存在就是没安装

新手编译示例

cd swoole
phpize //如果命令不存在 请在前面加上php的实际路径
phpize //(ubuntu 没有安装phpize可执行命令:sudo apt-get install php-dev来安装phpize)
./configure
make 
sudo make install

swoole官方安装地址

php安装目录一般在:/usr/local/php
php.ini配置文件路径:/usr/local/php/etc/php.ini
swoole 安装目录放在/usr/local/src

1、下载安装包

$ sudo wget https://github.com/swoole/swoole-src/archive/v4.3.3.tar.gz
$ sudo tar zxvf swoole-src-2.0.6.tar.gz

tar 四个参数
x : 从 tar 包中把文件提取出来
z : 表示 tar 包是被 gzip 压缩过的,所以解压时需要用 gunzip 解压
v : 显示详细信息
f xxx.tar.gz指定被处理的文件是 xxx.tar.gz

$ cd swoole-src-2.0.6

安装方法【1】使用PECL 一键安装

注意: PECL发布时间晚于Github发布时间
Swoole项目已收录到PHP官方扩展库,除了手工下载编译外,还可以通过PHP官方提供的pecl命令,一键下载安装

pecl install swoole
配置php.ini
编译安装成功后,修改php.ini加入

extension=swoole.so
通过php -m或phpinfo()来查看是否成功加载了swoole.so,如果没有可能是php.ini的路径不对,可以使用php --ini来定位到php.ini的绝对路径。

安装方法【2】编译安装

使用安装 php 时生成的 phpize 来生成 configure 配置文件(可以用 whereis phpize查看路径,其中 php-config 和 phpize 所在的目录是相同的)

yum install -y openssl #如需wss/https需要安装openssl,而ws/http不需要
$ sudo /usr/bin/phpize
$ sudo ./configure  --enable-openssl  --with-php-config=/usr/bin/php-config #这个注意php-config的目录是你php真实安装路径
#如果不需要wss 可以删除 --enable-openssl 
#宝塔面板可以点击php查看安装路径 ,我的是在/www/server/php/72/bin/php-config
#如果是集成环境,需要使用名 find / -name "php-config" 查询路径。
$ sudo make && sudo make install
  • 开启swoole扩展
$ cd /etc/php.d/
$ sudo vim php.ini
; Enable xsl extension module
extension=swoole.so

  • 重启ApacheNginx服务(php-fpm服务也要重启)。
  • 查看拓展安装情况 php-m
$ php -m |grep swoole
swoole

3、重启php-fpm

service php-fpm restart

在phpinfo页面可以看到关于swoole的选项,说明安装成功。

官网搭建简单demoweb服务器

参考官方手册:https://linkeddestiny.gitbooks.io/easy-swoole/content/book/chapter01/echo_server.html

服务端 Server

创建一个Server.php文件并输入如下内容:

// Server
class Server
{
    private $serv;

    public function __construct() {
        $this->serv = new swoole_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 8,
            'daemonize' => false,
        ));

        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($this, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));

        $this->serv->start();
    }

    public function onStart( $serv ) {
        echo "Start\n";
    }

    public function onConnect( $serv, $fd, $from_id ) {
        $serv->send( $fd, "Hello {$fd}!" );
    }

    public function onReceive( swoole_server $serv, $fd, $from_id, $data ) {
        echo "Get Message From Client {$fd}:{$data}\n";
        $serv->send($fd, $data);
    }

    public function onClose( $serv, $fd, $from_id ) {
        echo "Client {$fd} close connection\n";
    }
}
// 启动服务器 Start the server
$server = new Server();

客户端 Client

创建一个Client.php文件并输入如下内容: Create a file named 'Client.php' and type in following codes:

<?php
class Client
{
    private $client;

    public function __construct() {
        $this->client = new swoole_client(SWOOLE_SOCK_TCP);
    }

    public function connect() {
        if( !$this->client->connect("127.0.0.1", 9501 , 1) ) {
            echo "Error: {$this->client->errMsg}[{$this->client->errCode}]\n";
        }

        fwrite(STDOUT, "请输入消息 Please input msg:");  
        $msg = trim(fgets(STDIN));
        $this->client->send( $msg );

        $message = $this->client->recv();
        echo "Get Message From Server:{$message}\n";
    }
}

$client = new Client();
$client->connect();

启动服务器

在Terminal下执行命令

php Server.php #即可启动服务器,

在另一个Terminal下执行

php Client.php

输入要发送的内容,即可发送消息到服务器,并收到来自服务器的消息。

下面是一个demo实例

搭建tcp 服务器

<?php
//创建服务器
$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
<?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 服务器
<?php
//创建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

<?php
//创建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
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
//指的服务器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")
}
</script>
</body>
</html>
<?php
//循环执行定时器
swoole_time_tick(2000,function($timer_id){
echo "执行 $timer_id \n";
});
//单次执行
swoole_time_after(3000,function(){
echo "3 秒后执行"
})
?>
<?php
//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();
?>
<?php
//进程创建
/*

*   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();
?>
<?php
//进程事件
//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<$worker_num;$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";
    });
    }

?>
<?php
//进程队列通信
$workers = [];//进程仓库
$worker_num = 2;//最大进程数
//批量创建进程
for($i = 0;$i<$worker_num;$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<$worker_num;$i++){
$ret = swoole_process::wait();//等待执行完成
$pid = $ret['pid'];
unset($workers[$pid]);
echo "子进程退出 $pid \n";
}

?>

<?php
//触发函数 异步执行 达到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
//创建锁对象
$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 "子进程退出";

?>
<?php
//dns查询
swoole_async_dns_lookup('[www.baidu.com',function($host,$ip)](http://www.baidu.com',function(%24host,%24ip)){
echo "$host,$ip";
})
?>

swoole 实现及时通信 服务器端

<?php
//服务器代码
//创建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()
?>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352