运行流程图
进程/线程结构图
一个简单的示例
/**
* Created by PhpStorm.
* User:ajiang
* Date: 2017/11/22 0022
* Time: 11:43
* 一个简单的swoole 服务器示例
*/
<?php
require_once dirname(__FILE__) . "/config/Bootstrap.php";
class Server
{
private $serv;
public $setting;
public $swooleTaskPidPath;
public $logger;
public function __construct($ip, $port)
{
$this->swooleTaskPidPath = BASE_PATH . DS . \Weicot\Core\Initialization::SWOOLE_TASK_PID_PATH;
$this->logger = new \Weicot\Core\Logger();
$swooleLogger = BASE_PATH . DS . "var/swoole/swoole_" . date('Ymd') . ".log";
$this->setting = [
'host' => $ip,
'port' => $port,
'env' => 'dev', //环境 dev|test|prod
'process_name' => "test", //swoole 进程名称
'worker_num' => 4, //一般设置为服务器CPU数的1-4倍
'task_worker_num' => 4, //task进程的数量
'task_ipc_mode' => 3, //使用消息队列通信,并设置为争抢模式
'task_max_request' => 10000, //task进程的最大任务数
// 'daemonize' => 1, //以守护进程执行
'max_request' => 10000,
'dispatch_mode' => 2,
'log_file' => $swooleLogger, //日志
];
$this->config();
$this->sevice();
}
/**
*
*/
public function config()
{
$this->serv = new swoole_server($this->setting["host"], $this->setting["port"]);
$this->serv->set([
'worker_num' => $this->setting['worker_num'], //工作进程数量
'task_worker_num' => $this->setting['task_worker_num'],
'task_ipc_mode ' => $this->setting['task_ipc_mode'],
'task_max_request' => $this->setting['task_max_request'],
'daemonize' => $this->setting['daemonize'], //是否作为守护进程
'max_request' => $this->setting['max_request'],
'dispatch_mode' => $this->setting['dispatch_mode'],
'log_file' => $this->setting['log_file'],
]);
}
public function getServiceInfo()
{
$this->outInfo("Swoole Version:" . swoole_version()); //输出swoole的版本
$ipString = $this->logger->arryToString(swoole_get_local_ip(), "\r\n"); //输出本机iP
$this->outInfo("Local Ip:" . $ipString);
}
/**
*
*/
public function sevice()
{
//增加新的监控的ip:post:mode
$this->serv->addlistener("::1", 9500, SWOOLE_SOCK_TCP);
//监听事件
$this->serv->on('Start', array($this, 'onStart')); //启动server时候会触发。
$this->serv->on('Connect', array($this, 'onConnect')); //client连接成功后触发。
$this->serv->on('Receive', array($this, 'onReceive')); //接收client发过来的请求
$this->serv->on('ManagerStart', array($this, 'onManagerStart')); //master进程启动后, fork出Manager进程, 然后触发ManagerStart
$this->serv->on('WorkerStart', array($this, 'onWorkerStart')); //manager进程启动,启动work进程的时候调用 workid表示第几个id, 从0开始。
$this->serv->on('WorkerStop', array($this, 'onWorkerStop')); //当一个work进程死掉后,会触发
$this->serv->on('task', array($this, 'onTask')); //开始任务
$this->serv->on('finish', array($this, 'onFinish')); ////TDDO 任务结束之后处理任务或者回调
$this->serv->on('Shutdown', array($this, 'onShutdown')); //关闭服务器时触发
$this->serv->on('Close', array($this, 'onClose')); //客户端断开触发
$this->serv->start(); //启动
}
/**
* @param $info
* @param bool $out
*/
public function outInfo($info, $out = false)
{
if (!$this->_setting['daemonize']) {
$this->logger->outInfo("Swoole SPE:" . getmygid(), $info);
} elseif ($out) {
$this->logger->outInfo("Swoole SPE:" . getmygid(), $info);
}
}
/**
* 设置swoole进程名称
* @param string $name swoole进程名称
*/
private function setProcessName($name)
{
if (function_exists('cli_set_process_title')) {
cli_set_process_title($name);
} else {
if (function_exists('swoole_set_process_name')) {
swoole_set_process_name($name);
} else {
trigger_error(__METHOD__ . " failed. require cli_set_process_title or swoole_set_process_name.");
}
}
}
/**
* Server启动在主进程的主线程回调此函数
* @param $serv
*/
public function onManagerStart(\swoole_server $server, $workerId)
{
$this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server manager worker start\n");
$this->setProcessName($this->_setting['process_name'] . '-manager');
// 引入SP入口文件
// require_once dirname(__FILE__) . "/config/Bootstrap.php";
}
/**
* worker start 加载业务脚本常驻内存
* @param $server
* @param $workerId
*/
public function onWorkerStart($serv, $workerId)
{
if ($workerId >= $this->_setting['worker_num']) {
$this->setProcessName($this->_setting['process_name'] . '-task');
} else {
$this->setProcessName($this->_setting['process_name'] . '-event');
}
$this->outInfo("Start Worker:" . $workerId);
}
/**
* 当一个work进程死掉后,会触发
* worker 进程停止
* @param $server
* @param $workerId
*/
public function onWorkerStop($serv, $workerId)
{
$this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server[{$serv->setting['process_name']} worker:{$workerId} shutdown\n");
$this->outInfo('Worker Stop:' . $workerId, true);
}
//启动server时候会触发。
public function onStart($serv)
{
$this->getServiceInfo();
$this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server master worker start\n");
$this->setProcessName($this->_setting['process_name'] . '-master');
$pid = "{$serv->master_pid}\n{$serv->manager_pid}"; //记录进程id,脚本实现自动重启
file_put_contents($this->swooleTaskPidPath, $pid);
}
/**
* 监听连接进入事件
* client连接成功后触发。
* @param $serv
* @param $fd
*/
public function onConnect($serv, $fd, $from_id)
{
$this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server connect[" . $fd . "]\n");
$a = $serv->send($fd, "Hello {$fd}!");
// var_dump($a); //成功返回true
}
/**
* 监听数据发送事件
* 接收client发过来的请求
* @param $serv
* @param $fd
* @param $from_id
* @param $data
*/
public function onReceive(swoole_server $serv, $fd, $from_id, $data)
{
echo "Get Message From Client {$fd}:{$data}\n";
if (!$this->_setting['daemonize']) {
echo "Get Message From Client {$fd}:{$data}\n\n";
}
$result = json_decode($data, true);
switch ($result['action']) {
case 'reload': //重启
$serv->reload();
break;
case 'close': //关闭Server 关闭时
$serv->shutdown();
break;
case 'status': //状态
$serv->send($fd, json_encode($serv->stats()));
break;
default:
$serv->task($data);
break;
}
}
//客户端断开触发
public function onClose($serv, $fd, $from_id)
{
echo "Client {$fd} close connection\n";
}
/***
* 用来处理任务
* @param $serv
* @param $task_id
* @param $from_id
* @param $data
* @return string
*
*/
public function onTask($serv, $task_id, $from_id, $data)
{
$this->outInfo("Task {$task_id} finish\r\n" . "Result: {$data}");
echo "This Task {$task_id} from Worker {$from_id}\n";
echo "Data: {$data}\n";
$fd = json_decode($data, true);
$serv->send($fd['fd'], "Data in Task {$task_id}");
$serv->close($fd['fd']);
echo "Task {$task_id}'s result";
return "=====================";
}
/**
* 监听连接Finish事件
* @param $serv
* @param $task_id
* @param $data
*/
public function onFinish($serv, $task_id, $data)
{
// TDDO: 任务结束之后处理任务或者回调
//var_dump($data);
// $serv->close($data["fd"]);
echo "Task {$task_id} finish\n";
echo "Result: {$data}\n";
}
/**
* 此事件在Server 关闭时以及 结束时发生
*/
public function onShutdown($serv)
{
if (file_exists($this->swooleTaskPidPath)) {
unlink($this->swooleTaskPidPath);
}
if (!$this->setting['daemonize']) {
echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server shutdown\n";
}
}
}
// 启动服务器
$server = new Server("192.168.1.111", "2015");
转载请注明:(●--●) Hello.My Weicot » 一个简单的swoole 服务器示例