本文共 3483 字,大约阅读时间需要 11 分钟。
epoll模式主要是直接对socket进行监听,无需轮询,当socket状态发生变化时会自动触发相应的事件处理。这意味着 epoll 模式能够高效地管理网络连接,减少资源消耗。
以下是关于epoll模式和Worker类的实现细节:
Worker类的基本结构
Worker类是一个用于管理socket监听和处理连接的类,主要包含以下属性和方法:属性
socket:用于存储当前socket资源。onConnect:连接建立时的回调函数。reusePort:是否允许端口复用。workerNum:子进程的数量。allSocket:存储所有socket资源。addr:监听地址和端口。方法
__construct($socket_address):初始化socket地址和端口。start():启动socket监听。fork():创建子进程,处理客户端连接。accept():设置socket选项和监听端口。onConnect和onMessage:连接建立和消息接收的回调函数。socket监听与事件处理
在accept()方法中,我们设置socket选项,允许端口复用并开启多端口监听。通过stream_socket_server创建socket资源,并使用swoole_event_add添加事件处理函数。 子进程管理
fork()方法用于创建子进程,处理客户端连接。每个子进程负责接收客户端请求,并在连接建立时触发onConnect回调函数。 资源管理
在accept()方法中,我们创建资源流上下文,并设置socket选项。通过stream_context_set_option设置端口复用和地址复用选项,确保多进程环境下的负载均衡。 事件处理
当socket检测到可读事件时,触发相应的回调函数。onConnect回调函数处理连接建立事件,而onMessage回调函数处理消息接收事件。 消息处理
在onMessage回调函数中,读取客户端数据并响应。通过fread读取数据,判断是否为有效资源,若数据为空则关闭socket。 以下是Worker类的核心实现代码示例:
class Worker { protected $socket = NULL; public $onConnect = NULL; public $reusePort = 1; public $workerNum = 2; public $allSocket; public $addr; public function __construct($socket_address) { $this->addr = $socket_address; } public function start() { $this->fork(); } public function fork() { for ($i = 0; $i < $this->workerNum; $i++) { $pid = pcntl_fork(); if ($pid < 0) { exit("创建失败"); } elseif ($pid > 0) { // 父进程处理子进程 } else { echo "zi"; $this->accept(); exit; } } } public function accept() { $opts = array( "socket" => array( "backlog" => 10240, ), ); $context = stream_context_create($opts); stream_context_set_option($context, "socket", "so_reuseport", 1); stream_context_set_option($context, "socket", "so_reuseaddr", 1); $this->socket = stream_socket_server($this->addr, $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $context); swoole_event_add($this->socket, function ($fd) { $clientSocket = stream_socket_accept($fd); if (!empty($clientSocket) && is_callable($this->onConnect)) { echo "连接事件触发", (int)$clientSocket, PHP_EOL; call_user_func($this->onConnect, $clientSocket); } }); swoole_event_add($clientSocket, function ($fd) { $buffer = fread($fd, 1024); if (empty($buffer)) { if (!is_resource($fd) || feof($fd)) { fclose($fd); } } if (!empty($buffer) && is_callable($this->onMessage)) { call_user_func($this->onMessage, $fd, $buffer); } }); }} 以下是使用示例:
$worker = new Worker("tcp://0.0.0.0:9801");$worker->reusePort = true;$worker->onConnect = function ($fd) { echo "连接事件触发", (int)$fd, PHP_EOL;};$worker->onMessage = function ($conn, $message) { var_dump("123"); $content = "123123123"; $http_resonse = "HTTP/1.1 200 OK"; $http_resonse .= "Content-Type: text/html;charset=UTF-8"; $http_resonse .= "Connection: keep-alive"; $http_resonse .= "Server: php socket server"; $http_resonse .= "Content-length: " . strlen($content); $http_resonse .= $content; fwrite($conn, $http_resonse);};$worker->start(); 通过上述实现,我们可以高效地管理网络连接,处理大量客户端请求。epoll模式的异步特性使得该实现能够在高负载环境下保持稳定性能。
转载地址:http://egvfk.baihongyu.com/