经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » PHP » 查看文章
Swoole 整合成一个小框架 - it-world
来源:cnblogs  作者:it-world  时间:2019/11/7 21:34:19  对本文有异议

效果



命令如下:

    php index.php 可以查看到上图

    php index.php start 开启服务(Debug模式)

    php index.php start -d 开启服务(Daemon模式)

    php index.php status 查看服务状态

    php index.php reload 服务热加载

    php index.php stop 关闭服务

index.php 这是文件名称,大家叫什么都可以。

目录结构如下:

    ├─ controller    
    │     ├── ...    
    ├─ client    
    │  ├─ websocket    
    │     ├── ...    
    │  ├─ tcp    
    │     ├── ...    
    ├─ server    
    │  ├─ config    
    │     ├── config.php    
    │  ├─ core    
    │     ├── Common.php    
    │     ├── Core.php    
    │     ├── HandlerException.php    
    │  ├─ log  -- 需要 读/写 权限    
    │     ├── ...    
    ├─ index.php

目前就这几个文件,后期研究新的知识点会直接集成到这里面。

说说实现了什么:

1、启动了 WebSocket、HTTP、TCP、UDP 等服务。

2、WebSocket 例子,在 client/websocket 文件夹,实现了视频弹幕。

3、HTTP 例子,在浏览器直接访问:http://ip:port,逻辑代码在 controller 文件夹。

4、TCP 例子,在 client/tcp 文件夹。

5、UDP 例子,直接运行 netcat-u ip port 即可。

6、相关配置,在 server/config 文件夹。
代码

放不全,就放一个主要的文件吧(Core.php)。

 

  1. <?php
  2. if (!defined('SERVER_PATH')) exit("No Access");
  3. class Core
  4. {
  5. private static $serv;
  6. public function __construct() {
  7. set_error_handler(['HandlerException', 'appError']);
  8. register_shutdown_function(['HandlerException', 'fatalError']);
  9. }
  10. public static function run() {
  11. static::checkCli();
  12. static::checkExtension();
  13. static::showUsageUI();
  14. static::parseCommand();
  15. }
  16. protected static function checkCli() {
  17. if (php_sapi_name() !== 'cli') {
  18. exit(output('服务只能运行在 cli sapi 模式下'));
  19. }
  20. }
  21. protected static function checkExtension() {
  22. if (!extension_loaded('swoole')) {
  23. exit(output('请安装 swoole 扩展'));
  24. }
  25. }
  26. protected static function showUsageUI() {
  27. global $argc;
  28. if ($argc <= 1 || $argc >3) {
  29. echo PHP_EOL;
  30. echo "----------------------------------------".PHP_EOL;
  31. echo "| Swoole |".PHP_EOL;
  32. echo "|--------------------------------------|".PHP_EOL;
  33. echo '| USAGE: php index.php commond |'.PHP_EOL;
  34. echo '|--------------------------------------|'.PHP_EOL;
  35. echo '| 1. start 以debug模式开启服务 |'.PHP_EOL;
  36. echo '| 2. start -d 以daemon模式开启服务 |'.PHP_EOL;
  37. echo '| 3. status 查看服务状态 |'.PHP_EOL;
  38. echo '| 4. reload 热加载 |'.PHP_EOL;
  39. echo '| 5. stop 关闭服务 |'.PHP_EOL;
  40. echo "----------------------------------------".PHP_EOL;
  41. echo PHP_EOL;
  42. exit;
  43. }
  44. }
  45. protected static function parseCommand() {
  46. global $argv;
  47. $command = $argv[1];
  48. $option = isset( $argv[2] ) ? $argv[2] : '' ;
  49. switch ($command) {
  50. case 'start':
  51. if ($option === '-d') { //以daemon形式启动
  52. get_config(['set@daemonize' => true]);
  53. }
  54. self::workerStart();
  55. break;
  56. case 'status':
  57. self::workerStatus();
  58. break;
  59. case 'reload':
  60. self::workerReload();
  61. break;
  62. case 'stop':
  63. self::workerStop();
  64. break;
  65. default:
  66. echo "Bad Command.".PHP_EOL;
  67. }
  68. }
  69. protected static function workerStart() {
  70. $config = get_config();
  71. self::$serv = new swoole_websocket_server($config['ip'], $config['websocket_port']);
  72. self::$serv->set($config['set']);
  73. self::$serv->on('Start', function ($serv) use ($config) {
  74. $start = new OnStart();
  75. $start::run($serv, $config);
  76. });
  77. self::$serv->on('ManagerStart', function ($serv) use ($config) {
  78. $manager_start = new OnManagerStart();
  79. $manager_start::run($serv, $config);
  80. });
  81. self::$serv->on('WorkerStart', function ($serv, $worker_id) use ($config) {
  82. $worker_start = new OnWorkerStart();
  83. $worker_start::run($serv, $worker_id, $config);
  84. });
  85. //TCP
  86. $tcp = self::$serv->listen($config['ip'], $config['tcp_port'], SWOOLE_SOCK_TCP);
  87. $tcp->set($config['tcp_set']);
  88. $tcp->on('Receive', function ($serv, $fd, $reactor_id, $data) {
  89. $receive = new OnReceive();
  90. $receive::run($serv, $fd, $reactor_id, $data);
  91. });
  92. //UDP
  93. $udp = self::$serv->listen($config['ip'], $config['udp_port'], SWOOLE_SOCK_UDP);
  94. $udp->set($config['udp_set']);
  95. $udp->on('Packet', function ($serv, $data, $client_info) {
  96. $packet = new OnPacket();
  97. $packet::run($serv, $data, $client_info);
  98. });
  99. self::$serv->on('Task', function ($serv, $task_id, $src_worker_id, $data) use ($config) {
  100. $task = new OnTask();
  101. $dataArr = json_decode($data, true);
  102. switch ($dataArr['server']) {
  103. case "tcp":
  104. $task::tcp_task_run($serv, $task_id, $src_worker_id, $data);
  105. break;
  106. case "ws":
  107. $task::ws_task_run($serv, $task_id, $src_worker_id, $data);
  108. break;
  109. }
  110. });
  111. self::$serv->on('Open', function ($serv, $request) {
  112. echo output("onOpen: handshake success with fd={$request->fd}");
  113. });
  114. self::$serv->on('Message', function ($serv, $frame) {
  115. $message = new OnMessage();
  116. $message::run($serv, $frame);
  117. });
  118. self::$serv->on('Request', function ($request, $response) {
  119. $req = new OnRequest();
  120. $req::run($request, $response);
  121. });
  122. self::$serv->on('Finish', function ($serv, $task_id, $data) {
  123. $finish = new OnFinish();
  124. $finish::run($serv, $task_id, $data);
  125. });
  126. self::$serv->on('Close', function ($serv, $fd, $reactor_id){
  127. try {
  128. echo output('客户端关闭');
  129. } catch(Exception $e) {
  130. }
  131. });
  132. self::$serv->on('Shutdown', function ($serv) {
  133. echo output("服务关闭");
  134. });
  135. self::showProcessUI();
  136. self::$serv->start();
  137. }
  138. protected static function workerStatus() {
  139. $config = get_config();
  140. if (!file_exists($config['master_pid_file']) ||
  141. !file_exists($config['manager_pid_file']) ||
  142. !file_exists($config['worker_pid_file']) ) {
  143. echo output("暂无启动的服务");
  144. return false;
  145. }
  146. self::showProcessUI($config);
  147. $masterPidString = trim(@file_get_contents($config['master_pid_file']));
  148. $masterPidArr = explode( '-', $masterPidString);
  149. echo str_pad("Master", 18, ' ', STR_PAD_BOTH ).
  150. str_pad($config['master_process_name'], 26, ' ', STR_PAD_BOTH ).
  151. str_pad($masterPidArr[0], 16, ' ', STR_PAD_BOTH ).
  152. str_pad($masterPidArr[1], 16, ' ', STR_PAD_BOTH ).
  153. str_pad($masterPidArr[2], 16, ' ', STR_PAD_BOTH ).PHP_EOL;
  154. $managerPidString = trim(@file_get_contents($config['manager_pid_file']));
  155. $managerPidArr = explode( '-', $managerPidString);
  156. echo str_pad("Manager", 20, ' ', STR_PAD_BOTH ).
  157. str_pad($config['manager_process_name'], 24, ' ', STR_PAD_BOTH ).
  158. str_pad($managerPidArr[0], 16, ' ', STR_PAD_BOTH ).
  159. str_pad($managerPidArr[1], 16, ' ', STR_PAD_BOTH ).
  160. str_pad($managerPidArr[2], 16, ' ', STR_PAD_BOTH ).PHP_EOL;
  161. $workerPidString = rtrim(@file_get_contents($config['worker_pid_file']), '|' );
  162. $workerPidArr = explode( '|', $workerPidString );
  163. if (isset($workerPidArr) && !empty($workerPidArr)) {
  164. foreach ($workerPidArr as $key => $val) {
  165. $v = explode( '-', $val);
  166. echo str_pad("Worker", 18, ' ', STR_PAD_BOTH ).
  167. str_pad($config['worker_process_name'], 26, ' ', STR_PAD_BOTH ).
  168. str_pad($v[0], 16, ' ', STR_PAD_BOTH ).
  169. str_pad($v[1], 16, ' ', STR_PAD_BOTH ).
  170. str_pad($v[2], 16, ' ', STR_PAD_BOTH ).PHP_EOL;
  171. }
  172. }
  173. $taskPidString = rtrim(@file_get_contents($config['task_pid_file']), '|' );
  174. $taskPidArr = explode( '|', $taskPidString );
  175. if (isset($taskPidArr) && !empty($taskPidArr)) {
  176. foreach ($taskPidArr as $key => $val) {
  177. $v = explode( '-', $val);
  178. echo str_pad("Task", 18, ' ', STR_PAD_BOTH ).
  179. str_pad($config['task_process_name'], 24, ' ', STR_PAD_BOTH ).
  180. str_pad($v[0], 20, ' ', STR_PAD_BOTH ).
  181. str_pad($v[1], 12, ' ', STR_PAD_BOTH ).
  182. str_pad($v[2], 20, ' ', STR_PAD_BOTH ).PHP_EOL;
  183. }
  184. }
  185. }
  186. protected static function workerReload() {
  187. $config = get_config();
  188. if (!file_exists($config['master_pid_file'])) {
  189. echo output("暂无启动的服务");
  190. return false;
  191. }
  192. $masterPidString = trim(file_get_contents($config['master_pid_file']));
  193. $masterPidArr = explode( '-', $masterPidString);
  194. if (!swoole_process::kill($masterPidArr[0], 0)) {
  195. echo output("PID:{$masterPidArr[0]} 不存在");
  196. return false;
  197. }
  198. swoole_process::kill($masterPidArr[0], SIGUSR1);
  199. @unlink($config['worker_pid_file']);
  200. @unlink($config['task_pid_file']);
  201. echo output("热加载成功");
  202. return true;
  203. }
  204. protected static function workerStop() {
  205. $config = get_config();
  206. if (!file_exists($config['master_pid_file'])) {
  207. echo output("暂无启动的服务");
  208. return false;
  209. }
  210. $masterPidString = trim(file_get_contents($config['master_pid_file']));
  211. $masterPidArr = explode( '-', $masterPidString);
  212. if (!swoole_process::kill($masterPidArr[0], 0)) {
  213. echo output("PID:{$masterPidArr[0]} 不存在");
  214. return false;
  215. }
  216. swoole_process::kill($masterPidArr[0]);
  217. $time = time();
  218. while (true) {
  219. usleep(2000);
  220. if (!swoole_process::kill($masterPidArr[0], 0)) {
  221. unlink($config['master_pid_file']);
  222. unlink($config['manager_pid_file']);
  223. unlink($config['worker_pid_file']);
  224. unlink($config['task_pid_file']);
  225. echo output("服务关闭成功");
  226. break;
  227. } else {
  228. if (time() - $time > 5) {
  229. echo output("服务关闭失败,请重试");
  230. break;
  231. }
  232. }
  233. }
  234. return true;
  235. }
  236. protected static function showProcessUI() {
  237. $config = get_config();
  238. if ($config['set']['daemonize'] == true) {
  239. return false;
  240. }
  241. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  242. echo "|" . str_pad("启动/关闭", 92, ' ', STR_PAD_BOTH) . "|" . PHP_EOL;
  243. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  244. echo str_pad("Start success.", 50, ' ', STR_PAD_BOTH) .
  245. str_pad("php index.php stop", 50, ' ', STR_PAD_BOTH) . PHP_EOL;
  246. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  247. echo "|" . str_pad("版本信息", 92, ' ', STR_PAD_BOTH) . "|" . PHP_EOL;
  248. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  249. echo str_pad("Swoole Version:" . SWOOLE_VERSION, 50, ' ', STR_PAD_BOTH) .
  250. str_pad("PHP Version:" . PHP_VERSION, 50, ' ', STR_PAD_BOTH) . PHP_EOL;
  251. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  252. echo "|" . str_pad("IP 信息", 90, ' ', STR_PAD_BOTH) . "|" . PHP_EOL;
  253. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  254. echo str_pad("IP:" . $config['ip'], 50, ' ', STR_PAD_BOTH) .
  255. str_pad("PORT:" . $config['websocket_port'], 50, ' ', STR_PAD_BOTH) . PHP_EOL;
  256. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  257. echo "|" . str_pad("进程信息", 92, ' ', STR_PAD_BOTH) . "|" . PHP_EOL;
  258. echo str_pad("-", 90, '-', STR_PAD_BOTH) . PHP_EOL;
  259. echo str_pad("Swoole进程", 20, ' ', STR_PAD_BOTH) .
  260. str_pad('进程别名', 30, ' ', STR_PAD_BOTH) .
  261. str_pad('进程ID', 18, ' ', STR_PAD_BOTH) .
  262. str_pad('父进程ID', 18, ' ', STR_PAD_BOTH) .
  263. str_pad('用户', 18, ' ', STR_PAD_BOTH) . PHP_EOL;
  264. }
  265. protected static function signalHandler() {
  266. //TODO 未完成
  267. //swoole_process::signal(SIGINT, function ($signal) {
  268. // echo $signal;
  269. // return;
  270. //});
  271. }
  272. }

 



原文链接:http://www.cnblogs.com/it-3327/p/11815462.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号