设为首页收藏本站
天天打卡

 找回密码
 立即注册
搜索
查看: 101|回复: 18

php使用swoole实现TCP服务

[复制链接]

1

主题

40

回帖

104

积分

注册会员

积分
104
发表于 2024-4-19 20:16:32 | 显示全部楼层 |阅读模式
目录

这里以在Yii框架下示例

一:swoole配置TCP
  1. 'swoole' => [
  2.     // 日志文件路径
  3.     'log_file' => '@console/log/swoole.log',
  4.     // 设置swoole_server错误日志打印的等级,范围是0-5。低于log_level设置的日志信息不会抛出
  5.     'log_level' => 1,
  6.     // 进程的PID存储文件
  7.     'pid_file' => '@console/log/swoole.server.pid',

  8.     // HTTP协议配置
  9.     'http' => [
  10.         'host' => '0.0.0.0',
  11.         'port' => '8889',

  12.         // 异步任务的工作进程数量
  13.         'task_worker_num' => 4,
  14.     ],
  15.     // TCP协议配置
  16.     'tcp' => [
  17.         'host' => '0.0.0.0',
  18.         'port' => '14000',

  19.         // 异步任务的工作进程数量
  20.         'task_worker_num' => 4,

  21.         // 启用TCP-Keepalive死连接检测
  22.         'open_tcp_keepalive' => 1,
  23.         // 单位秒,连接在n秒内没有数据请求,将开始对此连接进行探测
  24.         'tcp_keepidle' => 5 * 60,
  25.         // 探测的次数,超过次数后将close此连接
  26.         'tcp_keepcount' => 3,
  27.         // 探测的间隔时间,单位秒
  28.         'tcp_keepinterval' => 60,

  29.         // 心跳检测,此选项表示每隔多久轮循一次,单位为秒
  30.         'heartbeat_check_interval' => 2 * 60,
  31.         // 心跳检测,连接最大允许空闲的时间
  32.         'heartbeat_idle_time' => 5 * 60,
  33.     ]
  34. ],
复制代码
二:swoole实现TCP服务基类
  1. <?php
  2. /**
  3. * @link http://www.u-bo.com
  4. * @copyright 南京友博网络科技有限公司
  5. * @license http://www.u-bo.com/license/
  6. */

  7. namespace console\swoole;

  8. use Yii;
  9. use yii\helpers\Console;
  10. use yii\helpers\ArrayHelper;

  11. /*
  12. * Swoole Server基类
  13. *
  14. * @author wangjian
  15. * @since 0.1
  16. */
  17. abstract class BaseServer
  18. {
  19.     /**
  20.      * @var Swoole\Server
  21.      */
  22.     public $swoole;
  23.     /**
  24.      * @var boolean DEBUG
  25.      */
  26.     public $debug = false;

  27.     /**
  28.      * __construct
  29.      */
  30.     public function __construct($httpConfig, $tcpConfig, $config = [])
  31.     {
  32.         $httpHost = ArrayHelper::remove($httpConfig, 'host');
  33.         $httpPort = ArrayHelper::remove($httpConfig, 'port');
  34.         $this->swoole = new \swoole_http_server($httpHost, $httpPort);
  35.         $this->swoole->set(ArrayHelper::merge($config, $httpConfig));

  36.         $this->swoole->on('start', [$this, 'onStart']);
  37.         $this->swoole->on('request', [$this, 'onRequest']);
  38.         $this->swoole->on('WorkerStart', [$this, 'onWorkerStart']);
  39.         $this->swoole->on('WorkerStop', [$this, 'onWorkerStop']);
  40.         $this->swoole->on('task', [$this, 'onTask']);
  41.         $this->swoole->on('finish', [$this, 'onTaskFinish']);

  42.         $this->swoole->on('shutdown', [$this, 'onShutdown']);

  43.         $tcpHost = ArrayHelper::remove($tcpConfig, 'host');
  44.         $tcpPort = ArrayHelper::remove($tcpConfig, 'port');
  45.         $tcpServer = $this->swoole->listen($tcpHost, $tcpPort, SWOOLE_SOCK_TCP);
  46.         $tcpServer->set($tcpConfig);
  47.         $tcpServer->on('connect', [$this, 'onConnect']);
  48.         $tcpServer->on('receive', [$this, 'onReceive']);
  49.         $tcpServer->on('close', [$this, 'onClose']);
  50.     }

  51.     /*
  52.      * 启动server
  53.      */
  54.     public function run()
  55.     {
  56.         $this->swoole->start();
  57.     }

  58.     /**
  59.      * Server启动在主进程的主线程时的回调事件处理
  60.      *
  61.      * @param swoole_server $server
  62.      */
  63.     public function onStart(\swoole_server $server)
  64.     {
  65.         $startedAt = $this->beforeExec();

  66.         $this->stdout("**Server Start**\n", Console::FG_GREEN);
  67.         $this->stdout("master_pid: ");
  68.         $this->stdout("{$server->master_pid}\n", Console::FG_BLUE);

  69.         $this->onStartHandle($server);

  70.         $this->afterExec($startedAt);
  71.     }

  72.     /**
  73.      * 客户端与服务器建立连接后的回调事件处理
  74.      *
  75.      * @param swoole_server $server
  76.      * @param integer $fd
  77.      * @param integer $reactorId
  78.      */
  79.     abstract public function onConnect(\swoole_server $server, int $fd, int $reactorId);

  80.     /**
  81.      * 当服务器收到来自客户端的数据时的回调事件处理
  82.      *
  83.      * @param swoole_server $server
  84.      * @param integer $fd
  85.      * @param integer $reactorId
  86.      * @param string $data
  87.      */
  88.     abstract public function onReceive(\swoole_server $server, int $fd, int $reactorId, string $data);

  89.     /**
  90.      * 当服务器收到来自客户端的HTTP请求时的回调事件处理
  91.      *
  92.      * @param swoole_http_request $request
  93.      * @param swoole_http_response $response
  94.      */
  95.     abstract public function onRequest(\swoole_http_request $request, \swoole_http_response $response);

  96.     /**
  97.      * Worker进程/Task进程启动时发生
  98.      *
  99.      * @param swoole_server $server
  100.      * @param integer $worker_id
  101.      */
  102.     abstract public function onWorkerStart(\swoole_server $server, int $worker_id);

  103.     /**
  104.      * Worker进程/Task进程终止时发生
  105.      *
  106.      * @param swoole_server $server
  107.      * @param integer $worker_id
  108.      */
  109.     abstract public function onWorkerStop(\swoole_server $server, int $worker_id);

  110.     /**
  111.      * 异步任务处理
  112.      *
  113.      * @param swoole_server $server
  114.      * @param integer $taskId
  115.      * @param integer $srcWorkerId
  116.      * @param mixed $data
  117.      */
  118.     abstract public function onTask(\swoole_server $server, int $taskId, int $srcWorkerId, mixed $data);

  119.     /**
  120.      * 异步任务处理完成
  121.      *
  122.      * @param swoole_server $server
  123.      * @param integer $taskId
  124.      * @param mixed $data
  125.      */
  126.     abstract public function onTaskFinish(\swoole_server $server, int $taskId, mixed $data);

  127.     /**
  128.      * 客户端与服务器断开连接后的回调事件处理
  129.      *
  130.      * @param swoole_server $server
  131.      * @param integer $fd
  132.      */
  133.     abstract public function onClose(\swoole_server $server, $fd);

  134.     /**
  135.      * Server正常结束时的回调事件处理
  136.      *
  137.      * @param swoole_server $server
  138.      */
  139.     public function onShutdown(\swoole_server $server)
  140.     {
  141.         $startedAt = $this->beforeExec();

  142.         $this->stdout("**Server Stop**\n", Console::FG_GREEN);
  143.         $this->stdout("master_pid: ");
  144.         $this->stdout("{$server->master_pid}\n", Console::FG_BLUE);

  145.         $this->onShutdownHandle($server);

  146.         $this->afterExec($startedAt);
  147.     }

  148.     /**
  149.      * Server启动在主进程的主线程时的自定义事件处理
  150.      *
  151.      * @param swoole_server $server
  152.      */
  153.     protected function onStartHandle(\swoole_server $server)
  154.     {

  155.     }

  156.     /**
  157.      * Server正常结束时的自定义事件处理
  158.      *
  159.      * @param swoole_server $server
  160.      */
  161.     protected function onShutdownHandle(\swoole_server $server)
  162.     {

  163.     }

  164.     /**
  165.      * 获取请求路由
  166.      *
  167.      * @param swoole_http_request $request
  168.      */
  169.     protected function getRoute(\swoole_http_request $request)
  170.     {
  171.         return ltrim($request->server['request_uri'], '/');
  172.     }

  173.     /**
  174.      * 获取请求的GET参数
  175.      *
  176.      * @param swoole_http_request $request
  177.      */
  178.     protected function getParams(\swoole_http_request $request)
  179.     {
  180.         return $request->get;
  181.     }

  182.     /**
  183.      * 解析收到的数据
  184.      *
  185.      * @param string $data
  186.      */
  187.     protected function decodeData($data)
  188.     {
  189.         return json_decode($data, true);
  190.     }

  191.     /**
  192.      * Before Exec
  193.      */
  194.     protected function beforeExec()
  195.     {
  196.         $startedAt = microtime(true);
  197.         $this->stdout(date('Y-m-d H:i:s') . "\n", Console::FG_YELLOW);
  198.         return $startedAt;
  199.     }

  200.     /**
  201.      * After Exec
  202.      */
  203.     protected function afterExec($startedAt)
  204.     {
  205.         $duration = number_format(round(microtime(true) - $startedAt, 3), 3);
  206.         $this->stdout("{$duration} s\n\n", Console::FG_YELLOW);
  207.     }

  208.     /**
  209.      * Prints a string to STDOUT.
  210.      */
  211.     protected function stdout($string)
  212.     {
  213.         if (Console::streamSupportsAnsiColors(\STDOUT)) {
  214.             $args = func_get_args();
  215.             array_shift($args);
  216.             $string = Console::ansiFormat($string, $args);
  217.         }
  218.         return Console::stdout($string);
  219.     }
  220. }
复制代码
三:swoole操作类(继承swoole基类)
  1. <?php
  2. /**
  3. * @link http://www.u-bo.com
  4. * @copyright 南京友博网络科技有限公司
  5. * @license http://www.u-bo.com/license/
  6. */

  7. namespace console\swoole;

  8. use Yii;
  9. use yii\db\Query;
  10. use yii\helpers\Console;
  11. use yii\helpers\VarDumper;
  12. use apps\sqjc\models\WaterLevel;
  13. use apps\sqjc\models\WaterLevelLog;
  14. use common\models\Bayonet;
  15. use common\models\Device;
  16. use common\models\DeviceCategory;

  17. /**
  18. * Swoole Server测试类
  19. *
  20. * @author wangjian
  21. * @since 1.0
  22. */
  23. class Server extends BaseServer
  24. {
  25.     /**
  26.      * @inheritdoc
  27.      */
  28.     public function onConnect($server, $fd, $reactorId)
  29.     {
  30.         $startedAt = $this->beforeExec();

  31.         $this->stdout("**Connection Open**\n", Console::FG_GREEN);
  32.         $this->stdout("fd: ");
  33.         $this->stdout("{$fd}\n", Console::FG_BLUE);

  34.         $this->afterExec($startedAt);
  35.     }

  36.     /**
  37.      * @inheritdoc
  38.      */
  39.     public function onReceive($server, $fd, $reactorId, $data)
  40.     {
  41.         $startedAt = $this->beforeExec();

  42.         $this->stdout("**Received Message**\n", Console::FG_GREEN);

  43.         $this->stdout("fd: ");
  44.         $this->stdout("{$fd}\n", Console::FG_BLUE);

  45.         $this->stdout("data: ");//接收的数据
  46.         $this->stdout("{$data}\n", Console::FG_BLUE);



  47.         $result = $server->send($fd, '回复消息');



  48.         $this->afterExec($startedAt);
  49.     }


  50.     /**
  51.      * @inheritdoc
  52.      */
  53.     public function onRequest($request, $response)
  54.     {
  55.         $startedAt = $this->beforeExec();

  56.         $this->stdout("**HTTP Request**\n", Console::FG_GREEN);

  57.         $this->stdout("fd: ");
  58.         $this->stdout("{$request->fd}\n", Console::FG_BLUE);

  59.         $response->status(200);
  60.         $response->end('success');

  61.         $this->afterExec($startedAt);
  62.     }

  63.     /**
  64.      * @inheritdoc
  65.      */
  66.     public function onClose($server, $fd)
  67.     {
  68.         $startedAt = $this->beforeExec();

  69.         $this->stdout("**Connection Close**\n", Console::FG_GREEN);

  70.         $this->stdout("fd: ");
  71.         $this->stdout("{$fd}\n", Console::FG_BLUE);

  72.         $this->afterExec($startedAt);
  73.     }



  74.     /**
  75.      * @inheritdoc
  76.      */
  77.     public function onTask($server, $taskId, $srcWorkerId, $data)
  78.     {
  79.         $startedAt = $this->beforeExec();

  80.         $this->stdout("New AsyncTask: ");
  81.         $this->stdout("{$taskId}\n", Console::FG_BLUE);
  82.         $this->stdout("{$data}\n", Console::FG_BLUE);

  83.         $server->finish($data);

  84.         $this->afterExec($startedAt);
  85.     }

  86.     /**
  87.      * @inheritdoc
  88.      */
  89.     public function onWorkerStop($server, $worker_id)
  90.     {
  91.         // Yii::$app->db->close();
  92.     }
  93.     /**
  94.      * @inheritdoc
  95.      */
  96.     public function onWorkerStart($server, $worker_id)
  97.     {
  98.         // Yii::$app->db->open();
  99.     }


  100.     /**
  101.      * @inheritdoc
  102.      */
  103.     public function onTaskFinish($server, $taskId, $data)
  104.     {
  105.         $startedAt = $this->beforeExec();

  106.         $this->stdout("AsyncTask finished: ");
  107.         $this->stdout("{$taskId}\n", Console::FG_BLUE);

  108.         $this->afterExec($startedAt);
  109.     }
  110. }
复制代码
四:操作TCP服务
  1. <?php
  2. /**
  3. * @link http://www.u-bo.com
  4. * @copyright 南京友博网络科技有限公司
  5. * @license http://www.u-bo.com/license/
  6. */

  7. namespace console\controllers;

  8. use Yii;
  9. use yii\helpers\Console;
  10. use yii\helpers\FileHelper;
  11. use yii\helpers\ArrayHelper;
  12. use console\swoole\Server;

  13. /**
  14. * WebSocket Server controller.
  15. *
  16. * @see https://github.com/tystudy/yii2-swoole-websocket/blob/master/README.md
  17. *
  18. * @author wangjian
  19. * @since 1.0
  20. */
  21. class SwooleController extends Controller
  22. {
  23.     /**
  24.      * @var string 监听IP
  25.      */
  26.     public $host;
  27.     /**
  28.      * @var string 监听端口
  29.      */
  30.     public $port;
  31.     /**
  32.      * @var boolean 是否以守护进程方式启动
  33.      */
  34.     public $daemon = false;
  35.     /**
  36.      * @var boolean 是否启动测试类
  37.      */
  38.     public $test = false;

  39.     /**
  40.      * @var array Swoole参数配置项
  41.      */
  42.     private $_params;

  43.     /**
  44.      * @var array Swoole参数配置项(HTTP协议)
  45.      */
  46.     private $_http_params;
  47.     /**
  48.      * @var array Swoole参数配置项(TCP协议)
  49.      */
  50.     private $_tcp_params;

  51.     /**
  52.      * @inheritdoc
  53.      */
  54.     public function beforeAction($action)
  55.     {
  56.         if (parent::beforeAction($action)) {
  57.             //判断是否开启swoole拓展
  58.             if (!extension_loaded('swoole')) {
  59.                 return false;
  60.             }

  61.             //获取swoole配置信息
  62.             if (!isset(Yii::$app->params['swoole'])) {
  63.                 return false;
  64.             }
  65.             $this->_params = Yii::$app->params['swoole'];
  66.             $this->_http_params = ArrayHelper::remove($this->_params, 'http');
  67.             $this->_tcp_params = ArrayHelper::remove($this->_params, 'tcp');

  68.             foreach ($this->_params as &$param) {
  69.                 if (strncmp($param, '@', 1) === 0) {
  70.                     $param = Yii::getAlias($param);
  71.                 }
  72.             }

  73.             $this->_params = ArrayHelper::merge($this->_params, [
  74.                 'daemonize' => $this->daemon
  75.             ]);

  76.             return true;
  77.         } else {
  78.             return false;
  79.         }
  80.     }
  81.     /**
  82.      * 启动服务
  83.      */
  84.     public function actionStart()
  85.     {
  86.         if ($this->getPid() !== false) {
  87.             $this->stdout("WebSocket Server is already started!\n", Console::FG_RED);
  88.             return self::EXIT_CODE_NORMAL;
  89.         }
  90.         $server = new Server($this->_http_params, $this->_tcp_params, $this->_params);
  91.         $server->run();
  92.     }

  93.     /**
  94.      * 停止服务
  95.      */
  96.     public function actionStop()
  97.     {
  98.         $pid = $this->getPid();
  99.         if ($pid === false) {
  100.             $this->stdout("Tcp Server is already stoped!\n", Console::FG_RED);
  101.             return self::EXIT_CODE_NORMAL;
  102.         }

  103.         \swoole_process::kill($pid);
  104.     }

  105.     /**
  106.      * 清理日志文件
  107.      */
  108.     public function actionClearLog()
  109.     {
  110.         $logFile = Yii::getAlias($this->_params['log_file']);
  111.         FileHelper::unlink($logFile);
  112.     }

  113.     /**
  114.      * 获取进程PID
  115.      *
  116.      * @return false|integer PID
  117.      */
  118.     private function getPid()
  119.     {
  120.         $pidFile = $this->_params['pid_file'];
  121.         if (!file_exists($pidFile)) {
  122.             return false;
  123.         }

  124.         $pid = file_get_contents($pidFile);
  125.         if (empty($pid)) {
  126.             return false;
  127.         }

  128.         $pid = intval($pid);
  129.         if (\swoole_process::kill($pid, 0)) {
  130.             return $pid;
  131.         } else {
  132.             FileHelper::unlink($pidFile);
  133.             return false;
  134.         }
  135.     }

  136.     /**
  137.      * @inheritdoc
  138.      */
  139.     public function options($actionID)
  140.     {
  141.         return ArrayHelper::merge(parent::options($actionID), [
  142.             'daemon',
  143.             'test'
  144.         ]);
  145.     }

  146.     /**
  147.      * @inheritdoc
  148.      */
  149.     public function optionAliases()
  150.     {
  151.         return ArrayHelper::merge(parent::optionAliases(), [
  152.             'd' => 'daemon',
  153.             't' => 'test',
  154.         ]);
  155.     }
  156. }
复制代码
以上就是php使用swoole实现TCP服务的详细内容,更多关于php swoole实现TCP服务的资料请关注脚本之家其它相关文章!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

1

主题

42

回帖

106

积分

注册会员

积分
106
发表于 2024-5-2 18:56:05 | 显示全部楼层
嘎嘎嘎嘎嘎嘎嘎

0

主题

66

回帖

131

积分

注册会员

积分
131
发表于 2024-5-12 14:35:59 | 显示全部楼层
同意你的观点,我们有共鸣。

0

主题

49

回帖

99

积分

注册会员

积分
99
发表于 2024-5-15 20:34:00 | 显示全部楼层
这个话题真是有趣,我也对它感兴趣。

1

主题

40

回帖

104

积分

注册会员

积分
104
发表于 2024-5-28 17:37:08 | 显示全部楼层
666666666666

4

主题

45

回帖

159

积分

注册会员

积分
159
发表于 2024-6-9 18:31:33 | 显示全部楼层
说得太好了,完全同意!

0

主题

58

回帖

115

积分

注册会员

积分
115
发表于 2024-6-11 01:43:40 | 显示全部楼层
太棒了!感谢分享这个信息!

1

主题

40

回帖

101

积分

注册会员

积分
101
发表于 2024-7-20 09:23:24 | 显示全部楼层
牛逼

0

主题

50

回帖

100

积分

注册会员

积分
100
发表于 2024-7-23 03:05:00 | 显示全部楼层
牛逼

1

主题

46

回帖

116

积分

注册会员

积分
116
发表于 2024-8-18 06:16:17 | 显示全部楼层
我们一起努力,共同解决问题吧。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|爱云论坛 - d.taiji888.cn - 技术学习 免费资源分享 ( 蜀ICP备2022010826号 )|天天打卡

GMT+8, 2024-11-15 05:32 , Processed in 0.098943 second(s), 26 queries .

Powered by i云网络 Licensed

© 2023-2028 正版授权

快速回复 返回顶部 返回列表