• [Swoole] 在Ubuntu下安装、快速开始


    本文主要讲述在 Ubuntu 下编译安装 Swoole,并根据官方文档给出的demo进行了测试和搬运,包括:TCP服务器、UDP服务器、HTTP服务器、WebSocket服务器、异步客户端、定时器和协程相关,通过模仿官方例子领略Swoole给PHPer带来全新的编程模式和思想。

    它弥补PHP在网络编程的不足。

    一、说明

    运行环境:win10 下的 UbuntuPHP7.2Swoole4.3

    参考文档: https://wiki.swoole.com/wiki/page/p-quickstart.html

    二、安装Swoole

    • 下载解压
    sudo wget https://github.com/swoole/swoole-src/archive/v4.3.6.tar.gz
    cp v4.3.6.tar.gz swoole-v4.3.6.tar.gz
    tar -zxvf swoole-v4.3.6.tar.gz
    cd swoole-v4.3.6
    
    • 安装依赖
    # 根据下面的编译提示进行选择安装
    
    sudo apt-get install php-dev
    sudo apt-get install autoconf
    
    • 编译安装
    # 根据自己 php 安装的目录
    cd swoole-v4.3.6
    /usr/local/php/bin/phpize
    ./configure
    make
    sudo make install
    

    make 的结果:

    ...
    ----------------------------------------------------------------------
    Libraries have been installed in:
       /home/fly/swoole-src-4.3.6/modules
    
    If you ever happen to want to link against installed libraries
    in a given directory, LIBDIR, you must either use libtool, and
    specify the full pathname of the library, or use the `-LLIBDIR'
    flag during linking and do at least one of the following:
       - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
         during execution
       - add LIBDIR to the `LD_RUN_PATH' environment variable
         during linking
       - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
       - have your system administrator add LIBDIR to `/etc/ld.so.conf'
    
    See any operating system documentation about shared libraries for
    more information, such as the ld(1) and ld.so(8) manual pages.
    ----------------------------------------------------------------------
    
    Build complete.
    Don't forget to run 'make test'.
    

    sudo make install 的结果:

    Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20170718/
    Installing header files:          /usr/local/php/include/php/
    
    • 配置 php.ini
    # 编译安装成功后,在 php.ini 文件加入
    extension=swoole.so
    
    # extension=/usr/lib/php/20170718/swoole.so
    

    查看是否加载 swoole 扩展

    php -m
    
    • 错误排查(可忽略)

    下面错误很明显,需要指定 php-conf 路径:

    configure: error: Cannot find php-config. Please use --with-php-config=PATH

    解决方法:

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

    三、快速入门

    a) TCP 服务器

    # 创建 php 文件
    vi tcp_server.php
    
    <?php
        //创建Server对象,监听 127.0.0.1:9501端口
        $serv = new SwooleServer("127.0.0.1", 9501); 
        
        //监听连接进入事件
        $serv->on('Connect', function ($serv, $fd) {  
            echo "Client: Connect.
    ";
        });
        
        //监听数据接收事件
        $serv->on('Receive', function ($serv, $fd, $from_id, $data) {
            $serv->send($fd, "Server: ".$data);
        });
        
        //监听连接关闭事件
        $serv->on('Close', function ($serv, $fd) {
            echo "Client: Close.
    ";
        });
        
        //启动服务器
        $serv->start(); 
    
    # 程序运行测试
    
    # 运行 server
    php tcp_server.php
    
    # 使用telnet 测试(退出telnet:Ctrl+] 回车,输入quit 回车)
    telnet 127.0.0.1 9501
    

    b) UDP 服务器

    vi udp_server.php
    
    <?php
        //创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP
        $serv = new swoole_server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); 
        
        //监听数据接收事件
        $serv->on('Packet', function ($serv, $data, $clientInfo) {
            $serv->sendto($clientInfo['address'], $clientInfo['port'], "Server ".$data);
            var_dump($clientInfo);
        });
        
        //启动服务器
        $serv->start(); 
    
    
    # 运行
    php udp_server.php
    
    # 使用 netcat 连接
    netcat -u 127.0.0.1 9502
    

    c) HTTP 服务器

    vi http_server.php
    
    <?php
        $http = new SwooleHttpServer("0.0.0.0", 9501);
        
        $http->on('request', function ($request, $response) {
            if ($request->server['path_info'] == '/favicon.ico' ||    $request->server['request_uri'] == '/favicon.ico') {
                return $response->end();
            }
            
            var_dump($request->get, $request->post);
            $response->header("Content-Type", "text/html; charset=utf-8");
            $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
        });
        
        $http->start();
    
    # 程序运行测试
    
    php http_server.php
    
    # 浏览器访问
    127.0.0.1:9501
    

    d) WebSocket 服务器

    WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。

    建立连接后客户端与服务器端就可以双向通信了。

    vi ws_server.php
    
    <?php
        //创建websocket服务器对象,监听0.0.0.0:9502端口
        $ws = new swoole_websocket_server("0.0.0.0", 9502);
        
        //监听WebSocket连接打开事件
        $ws->on('open', function ($ws, $request) {
            var_dump($request->fd, $request->get, $request->server);
            $ws->push($request->fd, "hello, welcome
    ");
        });
        
        //监听WebSocket消息事件
        $ws->on('message', function ($ws, $frame) {
            echo "Message: {$frame->data}
    ";
            $ws->push($frame->fd, "server: {$frame->data}");
        });
        
        //监听WebSocket连接关闭事件
        $ws->on('close', function ($ws, $fd) {
            echo "client-{$fd} is closed
    ";
        });
        
        $ws->start();
    
    # 程序运行
    
    php ws_server.php
    
    //使用浏览器JS代码如下
    
    var wsServer = 'ws://127.0.0.1:9502';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (evt) {
        console.log("Connected to WebSocket server.");
    };
    
    websocket.onclose = function (evt) {
        console.log("Disconnected");
    };
    
    websocket.onmessage = function (evt) {
        console.log('Retrieved data from server: ' + evt.data);
    };
    
    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
    };
    

    e) 定时器

    swoole提供了类似JavaScript的setInterval/setTimeout异步高精度定时器,粒度为毫秒级。

    vi timer_tick.php
    
    //每隔2000ms触发一次
    $timerId = swoole_timer_tick(2000, function ($timer_id) {
        echo "tick-2000ms
    ";
    });
    
    //9000ms后执行此函数
    swoole_timer_after(9000, function () use ($timerId) {
        echo "after-9000ms.
    ";
        
        //清除定时器
        swoole_timer_clear($timerId);
    });
    
    php timer_tick.php
    

    f) 同步、异步 TCP 客户端

    vi tcp_client.php
    
    <?php
        $client = new swoole_client(SWOOLE_SOCK_TCP);
        
        //连接到服务器
        if (!$client->connect('127.0.0.1', 9501, 0.5))
        {
            die("connect failed.");
        }
        //向服务器发送数据
        if (!$client->send("hello world"))
        {
            die("send failed.");
        }
        //从服务器接收数据
        $data = $client->recv();
        if (!$data)
        {
            die("recv failed.");
        }
        echo $data;
        //关闭连接
        $client->close();
    

    # 异步只能用于cli
    vi tcp_async_client.php
    
    <?php
        $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
        
        //注册连接成功回调
        $client->on("connect", function($cli) {
            $cli->send("hello world
    ");
        });
        
        //注册数据接收回调
        $client->on("receive", function($cli, $data){
            echo "Received: ".$data."
    ";
        });
        
        //注册连接失败回调
        $client->on("error", function($cli){
            echo "Connect failed
    ";
        });
        
        //注册连接关闭回调
        $client->on("close", function($cli){
            echo "Connection close
    ";
        });
        
        //发起连接
        $client->connect('127.0.0.1', 9501, 0.5);
    

    g) 协程客户端

    vi xxx.php
    
    <?php
        $http = new swoole_http_server("0.0.0.0", 9501);
        
        $http->on('request', function ($request, $response) {
            $db = new SwooleCoroutineMySQL();
            $db->connect([
                'host' => '127.0.0.1',
                'port' => 3306,
                'user' => 'user',
                'password' => 'pass',
                'database' => 'test',
            ]);
            $data = $db->query('select * from test_table');
            $response->end(json_encode($data));
        });
        
        $http->start();
    

    h) 协程:并发 shell_exec

    vi xxx.php
    
    <?php
        $c = 10;
        while($c--) {
            go(function () {
                //这里使用 sleep 5 来模拟一个很长的命令
                co::exec("sleep 5");
            });
        }
    

    i) 协程:Go + Chan + Defer

    参考官方文档:
    https://wiki.swoole.com/wiki/page/p-csp.html

  • 相关阅读:
    Js时间处理
    Css 显示删除条目效果
    vue权限控制菜单显示的简单实现
    js取对象的属性值循环
    标题的内容响应式设计
    将一个字符串当做一个方法名或对象的key
    JSON序列化和解析
    import 与export详解
    使用flask-mail扩展发送邮件
    正则表达式练习-计算器实现
  • 原文地址:https://www.cnblogs.com/reader/p/11665154.html
Copyright © 2020-2023  润新知