swoole为何从入门到放弃

swoole教程介绍为何从入门到放弃

swoole为何从入门到放弃

推荐(免费):swoole教程

一、swoole的源码包安装

  1. 下载swoole源码:git clone https://gitee.com/swoole/swoole.git
  2. 通过phpize(扩展php扩展模块,建立php外挂模块):

    • cd swoole
    • 执行:your/phpize/path
    • ./configure –with-php-config=your/php/path/bin/php-config
    • make && make install
  3. 可以看到swoole.so的位置

    • 我的位置是:/opt/soft/php/lib/php/extensions/no-debug-non-zts-20170718/
  4. 配置php.ini

    • 添加extension=swoole.so
  5. 通过php -m命令,可以看到php的扩展模块
  6. 检测swoole安装成功并且php支持swoole

    • cd your/swoole/path/examples/server
    • php echo.php(如果进程被阻塞,则说明成功)
    • netstat -anp | grep 9501(查看swoole开启的端口号)

二、网络通信引擎

学习swoole需要去翻阅文档,  swoole文档

1.通过swoole创建一个最简单的tcp服务

tcp服务端(tcp_server.php)

//创建Server对象,监听 127.0.0.1:9501端口 $serv = new swoole_server("127.0.0.1", 9501);  $serv->set([     'worker_num' => 4, // worker进程数,cpu 1-4倍     'max_request' => 100, ]);  /**  * 监听连接进入事件  * $fd 客户端连接服务端的唯一标识  * $reactor_id 线程id  */ $serv->on('connect', function ($serv, $fd, $reactor_id) {     echo "Client: {$fd} - {$reactor_id} - Connect.n"; });  //监听数据接收事件 $serv->on('receive', function ($serv, $fd, $reactor_id, $data) {     $serv->send($fd, "Server: ".$data); });  //监听连接关闭事件 $serv->on('close', function ($serv, $fd) {     echo "Client: Close.n"; });  //启动服务器 $serv->start();

tcp客户端(tcp_client.php)

// 创建tcp客户端 $client = new swoole_client(SWOOLE_SOCK_TCP);  // 连接tcp服务端 if (!$client->connect("127.0.0.1", 9501)) {     echo '连接失败';     exit; }  // php cli fwrite(STDOUT, '请输入:'); $msg = trim(fgets(STDIN));  // 发送消息给tcp服务端 if (!$client->send($msg)) {     echo '发送消息失败';     exit; }  // 接收 $result = $client->recv(); echo $result;

2.拓展:php的四种回调

  • 匿名函数
$server->on('Request', function ($req, $resp) {     echo "hello world"; });
  • 类静态方法
class A {     static function test($req, $resp)     {         echo "hello world";     } } $server->on('Request', 'A::Test'); $server->on('Request', array('A', 'Test'));
  • 函数
function my_onRequest($req, $resp) {     echo "hello world"; } $server->on('Request', 'my_onRequest');
  • 对象方法
class A {     function test($req, $resp)     {         echo "hello world";     } }  $object = new A(); $server->on('Request', array($object, 'test'));

小技巧:查看开启的worker进程:  ps aft | grep tcp_server.php


3. udp的服务端和客户端可以根据文档自行创建


4. http服务

// 监听所有地址和9501端口 $http = new swoole_http_server('0.0.0.0', 9501);  // 动静分离配置 $http->set([     // 开启静态请求     'enable_static_handler' => true,     // 静态资源目录     'document_root' => '/opt/app/code1/', ]);  $http->on('request', function ($request, $response) {     // 获取get请求的参数     $param = json_encode($request->get);     // 设置cookie     $response->cookie('name', 'ronaldo', time() + 1800);     // 输出到页面     $response->end("<h1>Hello Swoole - {$param}</h1>"); });  // 开启http服务 $http->start();

5.通过swoole创建websocket服务

websocket服务端(websocket_server.php)

// 监听所有地址和9502端口 $server = new swoole_websocket_server('0.0.0.0', 9502);  // 动静分离配置 $server->set([     // 开启静态请求     'enable_static_handler' => true,     // 静态资源目录     'document_root' => '/opt/app/swoole/websocket', ]); $server->on('open', function ($server, $request) {     echo "server:handshake success with fd - {$request->fd}n"; });  $server->on('message', function ($server, $frame) {     echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}n";     $server->push($frame->fd, "this is server"); });  $server->on('close', function ($server, $fd) {     echo "client - {$fd} - closen"; });  $server->start();

websocket客户端 (websockt_client.html

// 创建websocket实例         var websocketURL = "ws://www.rona1do.top:9502";         var websocket = new WebSocket(websocketURL);          // 实例化对象的onopen属性         websocket.onopen = function (ev) {             websocket.send("hello-websocket");             console.log("connect-swoole-success");         }          // 实例化对象的onmessage属性,接收服务端返回的数据         websocket.onmessage = function (ev) {             console.log("websockect-server-return-data:" + ev.data);         }          // close         websocket.onclose = function (ev) {             console.log("close");         }

6. 使用面向对象来优化websocket服务代码

class WebSocket {     const HOST = '0.0.0.0';     const PORT = 9502;      private $ws = null;      function __construct()     {         $this->ws = new swoole_websocket_server(self::HOST, self::PORT);         $this->ws->on('open', [$this, 'onOpen']);         $this->ws->on('message', [$this, 'onMessage']);         $this->ws->on('close', [$this, 'onClose']);         $this->ws->start();     }      // 监听websocket连接事件     function onOpen($server, $request) {         echo "server: handshake success with fd{$request->fd}n";     }      // 监听websocket消息接收事件     function onMessage($server, $frame) {         echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}n";         $server->push($frame->fd, "this is server");     }      // 监听客户端关闭事件     function onClose($server, $fd) {         echo "Client:{$fd} closesn";     } }

7.swoole中的task小案例

onTask:在task_worker进程内被调用。worker进程可以使用swoole_server_task函数向task_worker进程投递新的任务。当前的Task进程在调用onTask回调函数时会将进程状态切换为忙碌,这时将不再接收新的Task,当onTask函数返回时会将进程状态切换为空闲然后继续接收新的Task。

onFinish:当worker进程投递的任务在task_worker中完成时,task进程会通过swoole_server->finish()方法将任务处理的结果发送给worker进程。

class Websocket {      const HOST = '0.0.0.0';     const PORT = 9502;     private $ws = null;      public function __construct()     {         $this->ws = new swoole_websocket_server(self::HOST, self::PORT);         $this->ws->set([             'worker_num' => 2,             'task_worker_num' => 2, // 要想使用task必须要指明         ]);         $this->ws->on('open', [$this, 'onOpen']);         $this->ws->on('message', [$this, 'onMessage']);         $this->ws->on('task', [$this, 'onTask']);         $this->ws->on('finish', [$this, 'onFinish']);         $this->ws->on('close', [$this, 'onClose']);         $this->ws->start();     }      public function onOpen($server, $request)     {         echo "server:handshake success with fd:{$request->fd}n";     }      public function onMessage($server, $frame)     {         echo "receive from {$frame->fd}:{$frame->data}n";          // 需要投递的任务数据         $data = [             'fd' => $frame->fd,             'msg' => 'task',         ];         $server->task($data);          $server->push($frame->fd, 'this is server');     }      // 处理投递的任务方法,非阻塞     public function onTask($server, $task_id, $worker_id, $data)     {         print_r($data);         // 模拟大量数据的操作         sleep(10);         return "task_finish";     }          // 投递任务处理完毕调用的方法     public function onFinish($server, $task_id, $data)     {         echo "task_id:{$task_id}n";         echo "task finish success:{$data}n";     }          public function onClose($server, $fd)     {         echo "Client:close";     } }

以上就是

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享