swoole入门简介

1.swoole 应用

互联网

移动通信

企业软件

云计算

网络游戏

物联网

车联网

2.swoole是什么

  • 异步、并行、高性能

  • 纯C语言编写

  • php扩展

3.swoole 能做什么

  • 异步多线程服务器及客户段
  • 异步Myslq、redis、数据连接池、任务队列
  • http/websocket服务器/客户端
  • 异步文件读写
  • swoole 2.0 支持协程

swoole 的安装

1.要求

  • 环境cenos7/ubuntu16

  • php版本>=7.2

    注意:此是安装swoole4.6.0的要求,其他版本查询官方文档

2.安装pecl

$ wget http://pear.php.net/go-pear.phar
$ php go-pear.phar

3.安装swoole

$ sudo pecl  install swoole

4.配置sockets.ini

  • 进入/etc/php.d下

  • 在sockets.ini中将extension=swoole.so加到extension=sockets.so下面

  • 重启php-fpm

注意:在php.ini 中添加extension=swoole.so会报错。Unable to load dynamic library 'swoole.so’

启动服务

1.TCP服务器

  • Server.php
//创建Server对象,监听 127.0.0.1:9501 端口
$server = new Swoole\Server('127.0.0.1', 9501);

//监听连接进入事件
$server->on('Connect', function ($server, $fd) {
    echo "Client: Connect.\n";
});

//监听数据接收事件
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
    $server->send($fd, "Server: {$data}");
});

//监听连接关闭事件
$server->on('Close', function ($server, $fd) {
    echo "Client: Close.\n";
});

//启动服务器
$server->start(); 
  • 执行程序

    php server.php
    

2.UDP 服务器

  • udp_server.php

    $server = new Swoole\Server('127.0.0.1', 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
    
    //监听数据接收事件
    $server->on('Packet', function ($server, $data, $clientInfo) {
        var_dump($clientInfo);
        $server->sendto($clientInfo['address'], $clientInfo['port'], "Server:{$data}");
    });
    
    //启动服务器
    $server->start();
    
  • 启动服务

    php udp_server.php
    

3.HTTP 服务器

  • http_server.php
$http = new Swoole\Http\Server('0.0.0.0', 9501);

$http->on('Request', function ($request, $response) {
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end('<h1>Hello Swoole. #' . rand(1000, 9999) . '</h1>');
});

$http->start();
  • 启动服务

    php http_server.php
    
  • URL 路由

    应用程序可以根据 $request->server['request_uri'] 实现路由。如:http://127.0.0.1:9501/test/index/?a=1,代码中可以这样实现 URL 路由。

    $http->on('Request', function ($request, $response) {
        list($controller, $action) = explode('/', trim($request->server['request_uri'], '/'));
        //根据 $controller, $action 映射到不同的控制器类和方法
        (new $controller)->$action($request, $response);
    });
    

4.WebSocket 服务器

  • ws_server.php
//创建WebSocket Server对象,监听0.0.0.0:9502端口
$ws = new Swoole\WebSocket\Server('0.0.0.0', 9502);

//监听WebSocket连接打开事件
$ws->on('Open', function ($ws, $request) {
    $ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('Message', function ($ws, $frame) {
    echo "Message: {$frame->data}\n";
    $ws->push($frame->fd, "server: {$frame->data}");
});

//监听WebSocket连接关闭事件
$ws->on('Close', function ($ws, $fd) {
    echo "client-{$fd} is closed\n";
});

$ws->start();
  • 运行程序
php ws_server.php

可以使用 Chrome 浏览器进行测试,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);
};

5.定时器

Swore_alarm.php

<?php
use Swoole\Process;
use function Swoole\Coroutine\run;

run(function () {
    Process::signal(SIGALRM, function () {
        static $i = 0;
        echo "#{$i}\talarm\n";
        $i++;
        if ($i > 20) {
            Process::alarm(-1);
            Process::kill(getmypid());
        }
    });

    //100ms
    Process::alarm(100 * 1000);

    while(true) {
        sleep(0.5);
    }
});

6.异步TCP服务器

Task_server.php

<?php
$serv = new Swoole\Server('0.0.0.0', 9501);


//设置异步任务的工作进程数量
$serv->set([
    'task_worker_num' => 4
]);

//此回调函数在worker进程中执行
$serv->on('Receive', function($serv, $fd, $reactor_id, $data) {
    //投递异步任务
    $task_id = $serv->task($data);
    echo "Dispatch AsyncTask: id={$task_id}\n";
});

//处理异步任务(此回调函数在task进程中执行)
$serv->on('Task', function ($serv, $task_id, $reactor_id, $data) {
    echo "New AsyncTask[id={$task_id}]".PHP_EOL;
    //返回任务执行的结果
    $serv->finish("{$data} -> OK");
});

//处理异步任务的结果(此回调函数在worker进程中执行)
$serv->on('Finish', function ($serv, $task_id, $data) {
    echo "AsyncTask[{$task_id}] Finish: {$data}".PHP_EOL;
});

$serv->start();

7.TCP客户端

Tcp_client.php

<?php

$client = new Swoole\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('172.20.10.4', 9505, -1)) {
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");
echo $client->recv();
$client->close();

8.创建进程

Swoole_process.php

<?php
use Swoole\Process;

for ($n = 1; $n <= 3; $n++) {
    $process = new Process(function () use ($n) {
        echo 'Child #' . getmypid() . " start and sleep {$n}s" . PHP_EOL;
        sleep($n);
        echo 'Child #' . getmypid() . ' exit' . PHP_EOL;
    });
    $process->start();
}
for ($n = 3; $n--;) {
    $status = Process::wait(true);
    echo "Recycled #{$status['pid']}, code={$status['code']}, signal={$status['signal']}" . PHP_EOL;
}
echo 'Parent #' . getmypid()

9.swoole锁机制详解与实现

Swore_lock.php

<?php

$lock = new Swoole\Lock(SWOOLE_MUTEX);
echo "[Master]create lock\n";
$lock->lock();
if (pcntl_fork() > 0)
{
    sleep(1);
    $lock->unlock();
}
else
{
    echo "[Child] Wait Lock\n";
    $lock->lock();
    echo "[Child] Get Lock\n";
    $lock->unlock();
    exit("[Child] exit\n");
}
echo "[Master]release lock\n";
unset($lock);
sleep(1);
echo "[Master]exit\n";

10.swoole与dns查询

Swoole_dns.php

<?php

Swoole\Coroutine\run(function () {
    $ip = Swoole\Coroutine\System::dnsLookup("www.baidu.com");
    echo $ip;
});

11.swoole异步文件读取

Swoole_readfile.php

<?php

$filename = __DIR__ . "/defer_client.php";
Swoole\Coroutine\run(function () use ($filename)
{
    $r = Swoole\Coroutine\System::readFile($filename);
    var_dump($r);
});

12.swoole异步写入文件

Swoole_writefile.php

<?php
$filename = __DIR__ . "/defer_client.php";
Swoole\Coroutine\run(function () use ($filename)
{
    $w = Swoole\Coroutine\System::writeFile($filename, "hello swoole!");
    var_dump($w);
});

13.swoole异步操作mysql

Swoole_mysql.php

<?php
use Swoole\Coroutine\MySQL;
use function Swoole\Coroutine\run;

run(function () {
    $swoole_mysql = new MySQL();
    $swoole_mysql->connect([
        'host'     => '127.0.0.1',
        'port'     => 3306,
        'user'     => 'root',
        'password' => '######',
        'database' => 'test',
    ]);
    $res = $swoole_mysql->query('select sleep(1)');
    var_dump($res);
});
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐