技术饭

php扩展swoole的基础使用

copylian    0 评论    8913 浏览    2018.10.25

Swoole:面向生产环境的 PHP 异步网络通信引擎,使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP + Swoole 作为网络通信框架,可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。

基础用法:

1、创建TCP服务器

<?php

//创建TCP服务器


/**

 * 创建TCP服务对象 new swoole_server($host, $port, $mode, $sock_type)

 * $host : 127.0.0.1      监听本地IP

 *         139.196.86.20  监听远程IP

 *         0.0.0.0        不限制IP

 * $port : 9501           端口号,小于1024需要root权限

 * $mode : SWOOLE_PROCESS 多进程的方式

 * $sock_type:SWOOLE_SOCK_TCP 默认TCP

 */


//创建对象,监听 127.0.0.1:9501端口

$serv = new swoole_server("0.0.0.0", 9501);


/**

 * 使用

 * $serv->on($event, $callback)

 * $event : 事件

 *         connect : 当建立连接的时 $serv:服务器信息, $fd:客户端信息

 *         receive : 当接收数据时 $serv:服务器信息, $fd:客户端信息, $from_id:ID, $data:数据

 *         close   : 关闭连接

 */


//连接

$serv->on('connect', function ($serv, $fd) {

      echo "建立连接\n";

});


//接收数据

$serv->on('receive', function ($serv, $fd, $from_id, $data) {

      //$serv->send($fd, "接收到数据: " . $data);

      echo "接收到数据:\n";

      var_dump($data);

});


//监听连接关闭事件

$serv->on('close', function ($serv, $fd) {

      echo "关闭连接\n";

});


//开启服务

$serv->start();

?>


2、创建UDP服务器

<?php

//创建UDP服务器


//创建UDP对象,监听 127.0.0.1:9501端口,类型为SWOOLE_SOCK_UDP

$serv = new swoole_server("0.0.0.0", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);


/**

 * 监听数据接收事件 packet

 * $serv : 服务器信息

 * $data : 数据

 * $fd     : 客户端信息

 */

$serv->on('packet', function ($serv, $data, $fd) {

    $serv->sendto($fd['address'], $fd['port'], "返回数据 " . $data);

    var_dump($fd);

});


//启动服务器

$serv->start();


//使用 nc -u 127.0.0.1 9501 做测试

?>


3、创建HTTP服务器

<?php

//创建HTTP服务器


/**

 * new swoole_http_server($host, $port) 继承于 swoole_server()

 */


//创建服务

$serv = new swoole_http_server('0.0.0.0', 9501);


/**

 * 接收请求

 * $request : 请求数据

 * $respone : 响应数据

 */

$server->on('request', function ($request, $response) {

      var_dump($request);

      $response->header('Content-Type', 'text/html;charset=utf-8');

      $response->end('返回数据:' . rand(100, 20000));

});


//启动服务

$server->start();


//使用 http://stest.copylian.com:9501/ 直接浏览器范围

?>


4、创建websocket服务器

<?php

//创建websocket服务器


/**

 * new swoole_websocket_server($host, $prot) 继承于 swoole_http_server()

 */


//创建websocket服务器对象,监听0.0.0.0:9501端口

$serv = new swoole_websocket_server("0.0.0.0", 9501);


/**

 * 监听打开

 * $serv : 服务器信息

 * $request : 请求信息

 */

$serv->on('open', function ($serv, $request) {

      var_dump($request);

      $serv->push($request->fd, "我是发送过去的数据!");

});


//消息事件

$serv->on('message', function ($serv, $request) {

      //echo "消息: " . $request->data . "\n";

      //$serv->push($request->fd, "数据: " . $request->data);

});


//关闭

$serv->on('close', function ($serv, $fd) {

      echo "关闭\n";

});


//启动服务

$serv->start();


//使用 js的 new WebSocket(wsServer) 做测试

?>


<script type="text/javascript">

//websocket地址

var wsServer = 'ws://139.196.86.20:9501';


//websocket实例化

var websocket = new WebSocket(wsServer);


//打开

websocket.onopen = function (evt) {

    console.log('连接成功');

    console.log(evt);

};


//发送消息

websocket.onmessage = function (evt) {

    console.log('返回数据');

    console.log(evt);

};


//关闭

websocket.onclose = function (evt) {

    console.log('关闭');

    console.log(evt);

};


//错误

websocket.onerror = function (evt, e) {

    console.log('错误');

    console.log(evt);

};

</script>


5、创建定时器

<?php

//循环执行,类似setInterval

swoole_timer_tick(1000, function ($timer_id) {

     echo 1;

});


//单次执行,类似setTimeout

swoole_timer_after(1000, function () {

      echo 2;

});

?>


6、创建异步TCP服务

<?php

//创建TCP服务

$server = new swoole_server('0.0.0.0', 9501);


//设置异步的进程工作数

$server->set(array('task_worker_num' => 5));


//投递异步任务

$server->on('receive', function ($server, $fd, $from_id, $data) {

      //异步ID

      $task_id = $server->task($data);

      echo "异步ID:$task_id\n";

});


//处理异步任务

$server->on('task', function ($server, $task_id, $from_id, $data) {

      echo "执行异步ID:$task_id\n";

      $server->finish("$data -> OK");

});


//执行完成

$server->on('finish', function ($server, $task_id, $data) {

      echo "执行完成\n";

});


//启动服务

$server->start();

?>


7、创建同步TCP客户端

<?php

//客户端tcp

$client = new swoole_client(SWOOLE_SOCK_TCP);


//连接

if (!$client->connect('127.0.0.1', 80, 5)) {

      die('连接失败!');

}


//发送数据

if (!$client->send('Hello World!')) {

      die('发送数据失败!');

}


//接收数据

$data = $client->recv();

if (!$data) {

      die("接收数据失败!");

}


//输出数据

echo $data;


//关闭连接

$client->close();

?>


8、创建异步TCP客户端

<?php

//客户端异步tcp

$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);


//连接

$client->on('connect', function ($client) {

$client->send('Hello World!');

});


//接收

$client->on('receive', function ($client, $data) {

      echo "Receive:$data\n";

});


//错误

$client->on('error', function ($client) {

      echo "Error\n";

});


//关闭

$client->on('close', function ($client) {

      echo "Close\n";

});


//发起连接

$client->connect('127.0.0.1', 80, 5);

?>


9、创建子进程事件

<?php

//进程数组

$workers = [];


//进程数

$workers_num = 3;


//创建 启动进程

for ($i = 0; $i < $workers_num; $i++) {

      //创建单独进程

      $process = new swoole_process('doProcess');

      //启动进程,并获取进程ID

      $pid = $process->start();

      //存入进程数组

      $workers[$pid] = $process;

}


//创建进程函数

function doProcess(swoole_process $process) {

      //子进程写入信息

      $process->write("PID:" . $process->pid);

      echo "写入信息:" . $process->pid . '---' . $process->callback . "\n";

}


//添加进程事件 向米格子进程添加需要执行的动作

foreach ($workers as $pid => $process) {

      //添加事件

      swoole_event_add($process->pipe, function ($pipe) use ($process) {

            //读取数据

            $data = $process->read();

            echo "接收到:" . $data . "\n";

      });

}

?>


<?php

//进程数组

$workers = [];


//进程数

$workers_num = 3;


//创建 启动进程

for ($i = 0; $i < $workers_num; $i++) {

      //创建单独进程

      //$process = new swoole_process('doProcess');

      $process = new swoole_process('doProcess', false, false);


      //开启队列,类似于全局函数

      $process->useQueue();


      //启动进程,并获取进程ID

      $pid = $process->start();


      //存入进程数组

      $workers[$pid] = $process;

}


//创建进程函数

function doProcess(swoole_process $process) {

      //子进程写入信息

      //$process->write("PID:" . $process->pid);

      //echo "写入信息:" . $process->pid . '---' . $process->callback . "\n";


      $recv = $process->pop(); //默认长度 8192

      echo "从主进程获取到数据:" . $recv . "\n";

      sleep(5);

      $process->exit(0);

}


//添加进程事件 向米格子进程添加需要执行的动作

foreach ($workers as $pid => $process) {

      //添加事件

      /*swoole_event_add($process->pipe, function ($pipe) use ($process) {

            //读取数据

            $data = $process->read();

            echo "接收到:" . $data . "\n";

      });*/

      $process->push('Hello 子进程' . $pid . "\n");

}


//等待子进程结束回收资源

for ($i = 0; $i < $workers_num; $i++) {

      //等待执行完成

      $ret = swoole_process::wait();

      $pid = $ret['pid'];

      unset($workers[$pid]);

      echo "子进程退出" . $pid . "\n";

}

?>

10、创建子进程事件

<?php

//触发函数 异步执行

swoole_process::signal(SIGALRM, function () {

static $i = 0;

echo $i . "\n";

$i++;

if ($i > 10) {

swoole_process::alarm('-1'); //清除定时器

}

});


//开启定时信号

swoole_process::alarm(100 * 100);

?>

11、锁机制

<?php

//创建锁对象

$lock = new swoole_lock(SWOOLE_MUTEX); //互斥锁


echo "创建互斥锁\n";


//锁定

$lock->lock();


if (pcntl_fork() > 0) {

      sleep(5);

      $lock->unlock(); //解锁

} else {

      echo "子进程 等待锁\n";

      $lock->lock(); //锁定

      echo "子进程获取锁\n";

      $lock->unlock();

      echo "子进程关闭锁\n";

}

echo "主进程释放锁\n";

unset($lock);

sleep(5);

echo "子进程退出\n";

?>

12、DNS轮询查询

<?php

//DNS轮询查询

swoole_async_dns_lookup('www.baidu.com', function ($host, $ip) {

      echo $ip . '-' . $host;

});

?>

13、异步IO

<?php 

//异步读取文件

swoole_async_readfile(__DIR__.'/readfile.txt',function($filename,$content){

      echo $filename . " - " . $content;

});

?>


<?php 

//异步写入

$content = 'Write File Test.';

swoole_async_writefile('writefile.txt',$content,function($filename){

      echo $filename;

},0);

?>


<?php 

//异步事件:打开资源

$fp = stream_socket_client("tcp://www.qq.com:80",$erron,$errstr,30);

fwrite($fp,"GET / HTTP/1.1\r\nHOST:www.qq.com\r\n\r\n");


//添加异步事件

swoole_event_add($fp,function($fp){

      //读取

      $resp = fread($fp,8192);

      var_dump($resp);


      //删除事件

      swoole_event_del($fp);

      fclose($fp);

});

echo '这个先执行完成'."\n\r";

?>

<?php 

//异步mysql操作

$db = new swoole_mysql();


//配置

$config = [

      'host' => '139.196.86.20',

      'user' => 'root',

      'password' => 'llc@126.comllc',

      'database' => 'aikehou',

      'charset' => 'utf8'

];


//连接数据库

$db->connect($config,function($db,$r){

      if($r === false){

            //连接失败

            var_dump($db->connect_errno,$db->connect_error);

            die('连接失败');

      } else {

            //成功

            $sql = 'show tables';

            $db->query($sql,function(swoole_mysql $db,$r){

                  if($r === false){

                        var_dump($db->error);

                        die('操作失败');

                  } else {

                       var_dump($db->affected_rows,$db->insert_id);

                 }

                 var_dump($r);

                 $db->close();

            });

      }

});

?>

测试代码:swoole.zip

参考资料:Swoole:面向生产环境的 PHP 异步网络通信引擎

基础教程:千锋教育PHP异步通信框架Swoole解读视频教程

只袄早~~~
感谢你的支持,我会继续努力!
扫码打赏,感谢您的支持!
php扩展 swoole 

文明上网理性发言!

  • 还没有评论,沙发等你来抢