Студенты, изучившие фреймворк workman, обнаружат, что суть workman заключается в использовании расширения сокетов PHP плюс расширения pcntl для реализации базовых сетевых сервисов и планирования нескольких процессов. Давайте обсудим, как использовать модуль сокета сопрограммы swool для реализации наших собственных служб TCP. Давайте напишем небольшой фрагмент тестового кода. Испытание. php-код выглядит следующим образом
$socket = new Co\Socket(AF_INET, SOCK_STREAM, 0); $socket->bind('127.0.0.1', 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); $data = $client->recv(64,10); var_dump('Recv:'.$data); $client->sendAll('reply at '.time()); $client->close(); } });
Мы выполняем
php test.php
Создайте новую консоль CMD и имитируйте TCP-клиент с помощью telnet. Вы можете увидеть следующие результаты:
telnet 127.0.0.1 9601 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. asd reply at 1559713416 Connection closed by foreign host
Вышесказанное показывает, что мы успешно установили простой TCP-сервер. И внимательные студенты обнаружат, что если у меня есть некоторые особенности поведения базы данных после recv, то мой TCP-сервер может принимать только ссылки и обрабатывать одну ссылку одновременно, а параллелизм близок к 1. Таким образом, мы можем внести небольшое улучшение, а именно:
$socket = new Co\Socket(AF_INET, SOCK_STREAM, 0); $socket->bind('127.0.0.1', 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); go(function () use ($client){ $data = $client->recv(64,10); var_dump('Recv:'.$data); //It takes time to simulate the database. Suppose our database also uses the cooperation API. \co::sleep(1); $client->sendAll('reply at '.time()); $client->close(); }); } });
Мы используем протокол, чтобы поместить логику после принятия соединения в другой дополнительный протокол, чтобы наш TCP-сервер мог продолжать принимать соединение, что улучшает наш параллелизм. Однако в реальном программировании мы не можем достичь полного 100% API совместного программирования, и моя машина также является многоядерным процессором, так как я могу максимально использовать свой процессор в данный момент? Таким образом, мы можем построить сервер протокола TCP с несколькими процессами, используя характеристики повторного использования портов и процесс swool.
Процесс внедрения
Поскольку в этой главе инкапсуляция всего процесса не является нашей заботой, поэтому мы напрямую используем компоненты процесса, инкапсулированные easysool.
composer require easyswoole/component
Чтобы реализовать мой класс процесса, код выглядит следующим образом
use Co\Socket; use EasySwoole\Component\Process\AbstractProcess; class Server extends AbstractProcess { protected function run($arg) { $socket = new Socket(AF_INET, SOCK_STREAM, 0); //The key is to allow reuse $socket->setOption(SOL_SOCKET,SO_REUSEPORT,true); $socket->setOption(SOL_SOCKET,SO_REUSEADDR,true); $socket->bind('127.0.0.1', 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); go(function () use ($client){ $data = $client->recv(64,10); var_dump('Recv:'.$data); //It takes time to simulate the database. Suppose our database also uses the cooperation API. \co::sleep(1); $client->sendAll('reply at '.time()); $client->close(); }); } }); } }
В приведенном выше коде мы добавляем возможность разрешить мультиплексирование портов, в противном случае в многопроцессорном режиме это приведет к сбою прослушивания. Мы тестируем пять процессов в режиме cli.
for ($i = 1;$i < 5;$i++){ $p = new Server("TcpServer.{$i}"); $p->getProcess()->start(); } //Main process to wait for recycle while($ret = \Swoole\Process::wait()) { echo "PID={$ret['pid']}\n"; }
Таким образом, мы просто реализуем службу протокола TCP с несколькими процессами. Одним словом, способность к сотрудничеству swool 4. X по-прежнему очень сильна. Это позволяет Php реализовать высокопроизводительный TCP-сервис с наименьшими затратами, а не изучать новый язык. Если требуется более совершенный код, пожалуйста, обратитесь к коду проекта http://easyswoole.com/рамки. Если есть студенты, которым это нравится, вы можете нажать на звездочку, адрес GitHub HTTPS://Github.com/easy-tool…