zoukankan      html  css  js  c++  java
  • 安装使用swoole

    swoole首页:https://www.swoole.com/

    方法1:使用pecl安装

      pecl install swoole

      注意,php版本必须是7.0以及7.0以上的版本。

     

    方法2:编译源码安装

    第一步:下载swoole的源码

      下载源码的时候要注意,swoole2.0及以后版本不再支持PHP5.x

    git clone  https://github.com/swoole/swoole-src.git

    第二步:进入源码目录,执行phpize命令

    第三步:配置php-config的路径

    ./configure --with-php-config=/usr/local/php/bin/php-config

    第四步:将php.ini中被禁止的proc_open、proc_get_status、system、exec、shell_exec这几个函数从其中删除,因为在make时要用到这几个函数。

    第五步:make

      注意:如果下载的swoole 2.x,而php版本低于7.0,在这一步会失败,请下载正确源码版本

    第六步:make test

    第七步检测是否安装成功

    php  -m

    使用swoole搭建一个http服务器

    <?php
    
        $http = new swoole_http_server("0.0.0.0",9501);
        $http->on("request", function($request, $response){
            print_r($request);
            print_r($response);
        });
    
        $http->start();
    

      向服务器发起请求:

    curl 123.123.123.123:9501/aaa/bbb/index.html
    

      运行结果:

    SwooleHttpRequest Object
    (
        [fd] => 1
        [header] => Array
            (
                [user-agent] => curl/7.29.0
                [host] => 123.123.123.123:9501
                [accept] => */*
            )
    
        [server] => Array
            (
                [request_method] => GET
                [request_uri] => /aaa/bbb/index.html
                [path_info] => /aaa/bbb/index.html
                [request_time] => 1531286716
                [request_time_float] => 1531286716.3838
                [server_port] => 9501
                [remote_port] => 46576
                [remote_addr] => 123.123.123.123
                [master_time] => 1531286716
                [server_protocol] => HTTP/1.1
                [server_software] => swoole-http-server
            )
    
        [request] =>
        [cookie] =>
        [get] =>
        [files] =>
        [post] =>
        [tmpfiles] =>
    )
    SwooleHttpResponse Object
    (
        [fd] => 1
        [header] =>
        [cookie] =>
        [trailer] =>
    )
    

      可以观察一下上面SwooleHttpRequest和SwooleHttpResponse的结构(属性)。

    使用http服务器返回数据

    <?php
        $http = new swoole_http_server("0.0.0.0",9501);
        $http->on("request", function($request, $response){
            $response->header("Content-Type","text/html;chatset=utf-8");
            $response->end("hello world
    ");
        });
    
        $http->start();
    

      运行脚本,然后请求服务器:

    [root@centos ~]# curl xxx.xxx.xxx.xxx:9501/aaa/bbb/index.html
    hello world
    

      

    创建WebSocket服务器

      显示index.html的websocket客户端

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body></body>
    <script>
    	let ws = new WebSocket("ws://ganlixin.cn:9501");
    
    	ws.onopen = function(){
    		console.log("connect success");
    	}
    
    	ws.onclose = function(){
    		console.log("closed")
    	}
    
    	ws.onmessage = function(res){
    		console.log(res.data)
    	}
    </script>
    </html>
    

      

      websocket服务器:

    <?php
        $ws = new swoole_websocket_server("0.0.0.0",9501);
    
        //打开连接
        $ws->on("open", function($serv, $request){
            echo "connected 
    ";
            //向客户端发送信息
            $serv->push($request->fd, "hello world
    ");
        });
    
        //接收到数据
        $ws->on("message", function($serv, $request){
            echo "received data
    ";
            $serv->push($request->fd, "get message from client : {$request->data}");
        });
    
        //关闭连接
        $ws->on("close", function(){
            echo "closed
    ";
        });
    
        $ws->start();
    

      

      运行index.html,看控制台,有信息输出:

      

    定时器

      面向过程的形式

    <?php
        //循环定时器
        //int swoole_timer_tick(int $ms, callable $callback, mixed $user_param);
        $timer_id = swoole_timer_tick(5000, function($timer_id) {
            echo "current time " . date("Y-m-d H:i:s",time()) . "
    ";
        });
        echo $timer_id;
    
        //清除定时器
        //swoole_timer_clear($timer_id);
    

      面向对象的形式

    <?php
        //循环定时器
        $server = new swoole_server("0.0.0.0", 9501);
        $timer_id = $server->tick(1000,function($timer_id){
            echo "timer_id : " . $timer_id . " current time " . date("Y-m-d H:i:s",time()) . "
    ";
        });
    
        //注意,没有$swoole_server->clear();
        swoole_timer_clear($timer_id);
    

      使用定时器,一般都是使用面向过程的形式,因为那样的话,可以不用指定ip以及port。

    异步TCP服务器

    <?php
        //创建TCP服务器,默认是同步阻塞工作模式
        $server = new swoole_server("0.0.0.0",9501);
    
        //设置异步进程数量
        $server->set( [ "task_worker_num" => 4 ]);
    
        //接收到请求时
        $server->on("receive", function($serv, $data, $fd){
            $task_id = $serv->task($data); //生成异步任务id
            echo "task id is " . $task_id . "
    ";
        });
    
        //处理异步任务
        $server->on("task", function($serv, $task_id, $from_id, $data){
            echo "执行异步任务 task_id : $task_id 
    ";
            $serv->finish("data -> OK");
        });
    
        $server->on("finish", function($serv, $task_id, $data){
            echo "执行任务{$task_id}完成
    ";
        });
    
        $server->start();
    ?>
    

      多次访问服务器绑定的端口,会看到服务器控制台输出内容如下

    [root@centos index]# php index.php
    task id is 0
    执行异步任务 task_id : 0
    执行任务0完成
    task id is 1
    执行异步任务 task_id : 1
    执行任务1完成
    task id is 2
    执行异步任务 task_id : 2
    执行任务2完成
    task id is 3
    执行异步任务 task_id : 3
    执行任务3完成
    

      

    TCP客户端

    <?php
        //创建tcp客户端
        //swoole_client->__construct(int $sock_type, int $is_sync = SWOOLE_SOCK_SYNC, string $key);
        $client = new swoole_client(SWOOLE_SOCK_TCP);
    
        //连接服务器
        //bool $swoole_client->connect(string $host, int $port, float $timeout = 0.5, int $flag = 0)
        $client->connect("123.123.123.123", 9501, 5) or die("连接失败");
    
        //发送数据request
        //int $swoole_client->send(string $data);
        $client->send("hello world");
    
        //接受服务器的response
        //string $swoole_client->recv(int $size = 65535, int $flags = 0);
        //第二个参数表示是否等到所有数据都到达之后再返回
        $res = $client->recv(65535);
        echo $res;
    

      

    异步TCP客户端

    <?php
        //创建一个异步tcp客户端
        $client = new swoole_client(SWOOLE_SOCK_TCP,SWOOLE_SOCK_ASYNC);
    
        //只有tcp客户端是异步的时候,可以绑定事件
        $client->on("connect", function($cli){
            echo "connect
    ";
        });
    
        $client->on("receive", function($cli, $data){
            echo "data : $data 
    ";
        });
    
        $client->on("err", function($cli){
            echo "error
    ";
        });
    
        $client->on("close", function($cli){
            echo "closed
    ";
        });
    
        $client->connect("ganlixin.cn",80,10);
    ?>
    

      

    创建进程执行指定任务

    <?php
        //创建一个函数,包含之后创建的进程要干的任务
        function doJob(swoole_process $worker){
    /*
            print_r($worker);
            SwooleProcess Object
                (
                    [pipe] => 5
                    [callback] => doJob
                    [msgQueueId] =>
                    [msgQueueKey] =>
                    [pid] => 22777
                    [id] =>
                )
    */
            //执行外部程序
            //bool swoole_process->exec(string $execfile, array $args)
            $worker->exec('/usr/local/apache/bin/apachectl',array("start"));
        }
    
        //创建进程,将要做的事情(上面指定的函数)传递给构造方法
        $process_1 = new swoole_process("doJob");
        $pid = $process_1->start();
        //echo $pid,"
    ";
    
        $process_2 = new swoole_process("doJob");
        $pid = $process_2->start();
        //echo $pid,"
    ";
    
        //等待进程结束
        swoole_process::wait();
    

      

     指定进程事件

    <?php
        //进程池
        $process_pool = array();
    
        //进程数量
        $process_num = 4;
    
        //创建任务
        function doJob(swoole_process $process){
            //向管道中写入自己的pid
            $process->write("my pid is $process->pid");
            echo "pid : $process->pid 已写入信息
    ";
            $process->callback;
        }
    
        for ( $i = 0; $i < $process_num; $i++ ) {
            $process = new swoole_process("doJob");
            $pid = $process->start();
            $process_pool[] = $process; //存入进程池
        }
    
        //向每一个子进程指定需要执行的操作
        foreach($process_pool as $process){
            swoole_event_add($process->pipe, function($pipe) use ($process){
                $data = $process->read();
                echo "接收到数据 $data
    ";
            });
        }
    

      运行:

    pid : 25176 已写入信息
    接收到数据 my pid is 25176
    pid : 25177 已写入信息
    接收到数据 my pid is 25177
    pid : 25175 已写入信息
    接收到数据 my pid is 25175
    pid : 25174 已写入信息
    接收到数据 my pid is 25174
    

      

    进程队列

    <?php
        //进程池
        $process_pool = array();
    
        //进程数
        $process_num = 4;
    
        //子进程要执行的任务
        function doJob(swoole_process $process){
            $recv_data = $process->pop();//默认8192字节
            echo "从主进程收到数据 $recv_data
    ";
            sleep(1);
            $process->exit(0);//进程退出
        }
    
        for ( $i = 0; $i < $process_num; $i++ ) {
            $process = new swoole_process("doJob",false,false);
            //加入进程池
            $process_pool[] = $process;
            $process->useQueue();//开启进程队列
            $process->start();
        }
    
        //主进程执行
        foreach($process_pool as $process){
            //主进程向子进程发送数据
            $process->push("hello, I'm your father, your pid is $process->pid
    ");
        }
    
        //等待子进程结束
        for ( $i = 0; $i < $process_num; $i++ ) {
            //array swoole_process::wait(bool $blocking = true);
            $process = swoole_process::wait();
            echo "子进程{$process["pid"]}退出
    ";
        }
    
        //销毁进程池
        unset($process_pool);
    ?>
    

      

      

    信号触发

    <?php
        swoole_process::signal(SIGALRM,function(){
            //每次收到SIGALRM信号就执行一次
            echo "one";
    
            /*
            满足某种条件是,取消定时触发信号
            if ( condition ){
                swoole_process::alarm(-1);
            }
            */
        });
    
        //单位是微秒 1秒=1000000微秒
        //一秒触发一次alarm信号
        swoole_process::alarm(1000000);
    
        //上面的代码等同于
        //swoole_timer_tick(1000,function(){
        //    echo "one";
        //});
    

      

    互斥锁

    <?php
        //创建互斥锁
        $mutex = new swoole_lock(SWOOLE_MUTEX);
    
        $mutex->lock();
        echo "父进程加锁
    ";
    
        if ( pcntl_fork() > 0){
            //主进程执行
            sleep(2);
            $mutex->unlock();
        } else {
            //子进程执行
            echo "子进程等待父进程解锁
    ";
            $mutex->lock();
            echo "子进程加锁
    ";
            $mutex->unlock();
            exit("子进程退出
    ");
        }
    
        echo "主进程释放锁
    ";
        unset($mutex);
    ?>
    

      运行结果:

    [root@centos index]# php mutex.php
    父进程加锁
    子进程等待父进程解锁
    主进程释放锁
    
    
    
    子进程加锁
    子进程退出
    

      

    DNS查询

      通过传入域名,返回ip。

    <?php
        swoole_async_dns_lookup("www.swoole.com", function($host, $ip){
            echo "{$host} : {$ip}
    ";
        });
    ?>
    

      

    异步读取文件

      在PHP中读取文件,如果是大文件,可能需要的时间就长一点,那么就要修改php配置参数。

    <?php
    
        //采取分段读的方式
        //bool swoole_async_read(string $filename, mixed $callback, int $size = 8192, int $offset = 0);
        swoole_async_read("./mutex.php", function($filename,$content){
            echo $content;
        },10);
    

      

      

    异步读取文件

      分段写入

    <?php
    
        $content = file_get_contents("beego.tar");
        
        //分段写入
        //swoole_async_write(string $filename, string $content, int $offset = -1, mixed $callback = NULL);
        //offset置为-1时,表示追加方式
        swoole_async_write("data.tar", $content,1);
    

      

     异步mysql

    <?php
        $mysql = new swoole_mysql();
    
        $config = array(
            "host"      => "localhost",
            "user"      => "root",
            "password"  => "123456",
            "database"  => "test",
            "charset"   => "utf8"
        );
    
        $mysql->connect($config, function(swoole_mysql $db, $result){
            if ($result === FALSE) {
                echo "$result->connect_errno , $result->connect_error
    ";
                exit();
            }
            echo "数据库连接成功
    ";
    
            $sql = "select * from demo";
    
            $db->query($sql, function($link, $result){
                if ($result === FALSE) {
                    echo "执行SQL失败
    ";
                    exit();
                }
                print_r($result);
                //$result保存着结果集
            });
        });
    ?>
    

      运行:

    [root@centos index]# php async_mysql.php
    数据库连接成功
    Array
    (
        [0] => Array
            (
                [id] => 1
                [name] => aaa
                [age] => 10
            )
    
        [1] => Array
            (
                [id] => 2
                [name] => bbb
                [age] => 20
            )
    
    )
    

      

      

  • 相关阅读:
    深入浅出Powershell——创建本地账号
    SharePoint快速调试技巧
    深入浅出PowerShell——设置用户群组
    深入浅出SharePoint——权限提升
    伪数组
    用例的类型与粒度
    将 RTC 客户端 API 用于可缩放的应用程序
    InstallShield 收藏
    开发工具总结
    WEB免费打印控件推荐
  • 原文地址:https://www.cnblogs.com/-beyond/p/8522401.html
Copyright © 2011-2022 走看看