Автор оригинала: David Wong.
1.1 установка исходного кода php7
1.1.1 получение исходного кода и установка
Получите исходный код php 7: www.php.net
Tar - xzvf... Unzip command . / configure -- prefix = / home / study / PHP install to a path, install GCC in advance, etc Make compile Make install
Файл выполнения исходного кода размещен в: мусорное ведро Каталог
PHP - M ා check the extension of PHP installation
1.1.2 упростить выполнение команд PHP
псевдоним Путь к команде для команды
vim /.bash_profile Alias PHP = / home / work / soft / PHP / bin / PHP Source /. Bash? Profile? Note
исходное имя файла Эффект: В настоящее время баш Чтение и выполнение в среде Имя файла Ввод команды. Используется для повторного выполнения только что измененного документа инициализации, такого как .bash_profile и .профиль Подождите Примечание: Эта команда обычно использует команду” . “Заменить” Например: источник/и т.д./профиль И ./etc/профиль Это эквивалентно.
PHP - I | grep php.ini ා find the PHP configuration file
1.2 компиляция и установка исходного кода swool
Получить исходный код swole: Получить исходный код swole:
phpize Это для расширения php Модульный, через phpize Можно построить php Подключаемый модуль не был решен настройка проблема
/Usr / local / PHP / bin / phpize ා execute this line of code in the directory to be executed ./configure --with-php-config=/usr/local/php/bin/php-config
make make install
Наконец, вы можете PHP В каталоге расширений swoole.so увеличить файл
1.3 комбинация двух мечей, php7 поддерживает swoole
В php.ini Добавить в файл: extension=swoole.so Чтобы узнать, было ли оно успешно добавлено: php-m
В swoole/примеры/сервер Более низкое выполнение php echo.php Проверьте, нужно ли выполнять порт: 9501
netstat -anp|grep 9501
2.1 Служба TCP и клиент TCP
2.1.1 Служба TCP
Официальный веб-сайт Swoole документ: создание TCP – сервера | создание UDP-сервера
//Create a server object and listen to port 127.0.0.1:9501
$serv = new swoole_server("127.0.0.1", 9501);
//The swoole server - > set function is used to set the parameters of the swoole server runtime
$serv->set([
'worker_num' = > 6, // number of worker processes, 1-4 times of CPU
'max_request' => 10000,
]);
/**
*Listen for connection entry events
*$FD unique identification of client connection
*$reactor? ID thread ID
*/
$serv->on('connect', function ($serv, $fd, $reactor_id) {
echo "Client: {$reactor_id} - {$fd}-Connect.\n";
});
/**
*Listening for data receiving events
* $reactor_id = $from_id
*/
$serv->on('receive', function ($serv, $fd, $reactor_id, $data) {
$serv->send($fd, "Server: {$reactor_id} - {$fd}".$data);
});
//Listen for connection closing events
$serv->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
//Start server
$serv->start(); тест tcp Серверный метод:
netstat -anp | grep 9501- принять
telnetДля входа на удаленный хост:telnet 127.0.0.1 9501 tcpКлиентский скрипт
Просмотреть текущий рабочий Номер процесса: ps -af | grep tcp_server.php
Чаевые: Для обеспечения целостности выполнения программы при изменении tcp Лучше установить плавный перезапуск после серверного скрипта рабочий процесс Плавно перезапустите рабочий процесс
2.1.2 Клиент TCP
Гигантская яма облачного сервера Alibaba-порт не открыт для внешнего мира!!! Если websocket не удается подключиться к серверу, отображаются заголовки рекомендаций
connect("127.0.0.1", 9501)) {
Echo "connection failed";
exit;
}
//PHP cli constant
Fwrite (stdout, "please enter message:");
$msg = trim(fgets(STDIN));
//Send message to TCP server server
$client->send($msg);
//Accept data from server
$result = $client->recv();
echo $result;2.2 Служба HTTP(обычно используемая)
$http = new swoole_http_server("0.0.0.0", 8811);
//Add test one: get parameters and print them out
//$http->on('request', function ($request, $response) {
// $response->cookie("singwa",'xsssss', time() + 1800);
// $response->end('sss'.json_encode($request->get));
//});
/**
* https://wiki.swoole.com/wiki/page/783.html
*Configure the root directory of the static file, which is used with enable? Static? Handler.
*When document root is set and enable static handler is set to true,
*When the underlying layer receives the HTTP request, it will first determine whether the file exists under the document root path,
*If it exists, the content of the file will be sent directly to the client, and the onrequest callback will not be triggered.
*/
$http->set(
[
'enable_static_handler' => true,
'document_root' => "/home/work/hdtocs/swoole_mooc/data",
]
);
$http->on('request', function($request, $response) {
//print_r($request->get);
$content = [
'date:' => date("Ymd H:i:s"),
'get:' => $request->get,
'post:' => $request->post,
'header:' => $request->header,
];
swoole_async_writefile(__DIR__."/access.log", json_encode($content).PHP_EOL, function($filename){
// todo
}, FILE_APPEND);
$response->cookie("singwa", "xsssss", time() + 1800);
$response->end("sss". json_encode($request->get));
});
$http->start();2.3 сервис websocket(ключ)
2.3.1 общий обзор
Веб-карман Протокол основан на TCP Новый сетевой протокол. Он реализует полный дуплекс браузера и сервера( полный дуплекс Связь — Разрешить серверу активно отправлять информацию клиенту
Зачем нужен websocket
- Дефекты:
HTTPСвязь для может быть инициирована только клиентом
Особенности Websocket
- Настройка в
TCPВыше соглашения - Низкая стоимость производительности, высокая эффективность связи
- Клиент может взаимодействовать с любым сервером
- Идентификатор протокола
wsвсиво - Постоянный сетевой протокол связи
2.3.2 реализация кейса
2.3.2.1 реализация сервера
1. Ориентированный на процесс: procedure_ws_server.php
$server = new swoole_websocket_server("0.0.0.0", 9912);
//Configure static file root, optional
$server->set(
[
'enable_static_handler' => true,
'document_root' => "/home/wwwroot/www.lingyuan88.com/public/swoole/data",
]
);
//Listen for websocket connection open event
$server->on('open', 'onOpen');
function onOpen($server, $request) {
print_r($request->fd);
}
//Listen for WS message events
$server->on('message', function (swoole_websocket_server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$server->push($frame->fd, "singwa-push-secesss");
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start(); 2. Оптимизация сервиса Websocket, базовая библиотека классов объектно-ориентированный: Оптимизация сервиса Websocket, базовая библиотека классов
class Ws {
CONST HOST = "0.0.0.0";
CONST PORT = 9912;
public $ws = null;
public function __construct() {
$this->ws = new swoole_websocket_server(self::HOST, self::PORT);
//Configure static file root, optional
$this->ws->set(
[
'enable_static_handler' => true,
'document_root' => "/home/wwwroot/www.lingyuan88.com/public/swoole/data",
]
);
$this->ws->on("open", [$this, 'onOpen']);
$this->ws->on("message", [$this, 'onMessage']);
$this->ws->on("close", [$this, 'onClose']);
$this->ws->start();
}
/**
*Listen for WS connection events
* @param $ws
* @param $request
*/
public function onOpen($ws, $request) {
print_r($request->fd);
}
/**
*Listen for WS message events
* @param $ws
* @param $frame
*/
public function onMessage($ws, $frame) {
echo "ser-push-message:{$frame->data}\n";
$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));
}
/**
* close
* @param $ws
* @param $fd
*/
public function onClose($ws, $fd) {
echo "clientid:{$fd}\n";
}
}
$obj = new Ws();2.3.2.2 реализация клиента
ws_client.html
Singwa swoole WS test
2.3.2.3 тестирование
1. пропуск WebSocket Проверка статического каталога файлов
2. пропуск HTTP Тестирование сервиса
2.4 использование асинхронных задач(ключ)
Сценарии использования
- Выполнение трудоемких операций (отправка широковещательной почты и т.д.)
Будьте осторожны:
- После того, как асинхронная задача будет доставлена , программа
Продолжит, не ждите завершения задачи, прежде чем продолжить выполнение вниз
class Ws {
CONST HOST = "0.0.0.0";
CONST PORT = 9912;
public $ws = null;
public function __construct() {
$this->ws = new swoole_websocket_server(self::HOST, self::PORT);
$this->ws->set(
[
'worker_num' => 2,
'task_worker_num' => 2,
]
);
//Register event callback function of server
$this->ws->on("open", [$this, 'onOpen']);
$this->ws->on("message", [$this, 'onMessage']);
$this->ws->on("task", [$this, 'onTask']);
$this->ws->on("finish", [$this, 'onFinish']);
$this->ws->on("close", [$this, 'onClose']);
$this->ws->start();
}
/**
*Listen for WS connection events
* @param $ws
* @param $request
*/
public function onOpen($ws, $request) {
var_dump($request->fd);
}
/**
*Listen for WS message events
* @param $ws
* @param $frame
*/
public function onMessage($ws, $frame) {
echo "ser-push-message:{$frame->data}\n";
// todo 10s
$data = [
'task' => 1,
'fd' => $frame->fd,
];
//Deliver asynchronous tasks
//Note: the program will continue to execute downward, and will not wait for the task to finish executing before continuing to execute downward
$ws->task($data);
//The client will receive the following information immediately
$ws->push($frame->fd, "server-push:".date("Y-m-d H:i:s"));
}
/**
* @param $serv
* @param $taskId
* @param $workerId
* @param $data
* @return string
*/
public function onTask($serv, $taskId, $workerId, $data) {
print_r($data);
//Time consuming scenario 10s
sleep(10);
Return "on task finish"; // tell worker and return $data to onfinish
}
/**
* @param $serv
* @param $taskId
* @param $data
*/
public function onFinish($serv, $taskId, $data) {
echo "taskId:{$taskId}\n";
echo "finish-data-sucess:{$data}\n";
}
/**
* close
* @param $ws
* @param $fd
*/
public function onClose($ws, $fd) {
echo "clientid:{$fd}\n";
}
}
$obj = new Ws();3.1 асинхронные, блокирующие и модели ввода-вывода(обязательно поймите.)
3.1.1 синхронный и асинхронный
Озабоченность вызывает Уведомление о сообщении Механизм;
Синхронизация: После выполнения вызова Немедленного возврата нет , но после возврата будет возвращен окончательный результат;
Асинхронный: После выполнения вызова/| Вызываемая сторона Верните сообщение сейчас , Но это не конечный результат 。 Вызывающий абонент информирует вызывающего абонента через статус, механизм уведомления и т.д. Или обрабатывает результат с помощью функции обратного вызова;
3.1.2 блочные и неблочные
Беспокойство вызывает Состояние, в котором вызывающий абонент ожидает, что вызываемый абонент вернет результат вызова.
Препятствие: Вызывающий абонент приостанавливается до тех пор , пока не будет возвращен результат вызова , вызывающий абонент может продолжить только после получения возвращенного результата.
Не блокируется: Вызывающий абонент не будет приостановлен до тех пор, пока не будет возвращен результат;
3.1.3 Модель ввода-вывода
Blocking IO: blocking IO Nonblocking IO: non blocking IO Multiplexing IO: multiplexing IO Signal driven IO: event driven IO Asynchronous IO: asynchronous IO
Реальное исполнение ИО Этапы процесса: Данные памяти ядра копирование в Память процесса в
3.2 асинхронный миллисекундный таймер свула
асинхронный Высокоточный таймер с детализацией миллисекунда
//Trigger every 2000ms
swoole_timer_tick(2000, function ($timer_id) {
echo "tick-2000ms\n";
});
//Execute this function after 3000ms
swoole_timer_after(3000, function () {
echo "after 3000ms.\n";
});3.3 ввод-вывод асинхронной файловой системы
Официальный веб-сайт Swoole документ: асинхронная файловая система ввода-вывода
3.3.1 асинхронное чтение
/**
*Read file
* __DIR__
*If the file does not exist, false will be returned
*File opened successfully returns true immediately
*After reading the data, the specified callback function will be called back.
*/
//Function style
$result = swoole_async_readfile(__DIR__."/1.txt", function($filename, $fileContent) {
echo "filename:".$filename.PHP_EOL; // \n \r\n
echo "content:".$fileContent.PHP_EOL;
});
//Namespace style
$result = Swoole\Async::readfile(__DIR__."/1.txt", function($filename, $fileContent) {
echo "filename:".$filename.PHP_EOL; // \n \r\n
echo "content:".$fileContent.PHP_EOL;
});
var_dump($result);
echo "start".PHP_EOL;3.3.2 асинхронная запись (например, в журнал)
$http->on('request', function($request, $response) {
$content = [
'date:' => date("Ymd H:i:s"),
'get:' => $request->get,
'post:' => $request->post,
'header:' => $request->header,
];
swoole_async_writefile(__DIR__."/access.log", json_encode($content).PHP_EOL, function($filename){
// todo
}, FILE_APPEND);
$response->end("response:". json_encode($request->get));
});3.4 подробная информация об асинхронном MySQL
class AsyncMySql {
/**
* @var string
*/
public $dbSource = "";
/**
*MySQL configuration
* @var array
*/
public $dbConfig = [];
public function __construct() {
//new swoole_mysql;
$this->dbSource = new Swoole\Mysql;
$this->dbConfig = [
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => 'test',
'database' => 'test',
'charset' => 'utf8',
];
}
public function update() {}
public function add() {}
/**
*MySQL execution logic
* @param $id
* @param $username
* @return bool
*/
public function execute($id, $username) {
$this->dbSource->connect($this->dbConfig, function($db, $result) use($id, $username) {
echo "mysql-connect".PHP_EOL;
if($result === false) {
var_dump($db->connect_error);
// todo
}
$sql = "select * from cmf_user where id=1";
//$sql = "update test set `username` = '".$username."' where id=".$id;
// insert into
// query (add select update delete)
$db->query($sql, function($db, $result){
//Select = > result returns the result content of the query
if($result === false) {
// todo
var_dump($db->error);
}elseif($result === true) {// add update delete
// todo
var_dump($db->affected_rows);
}else {
print_r($result);
}
$db->close();
});
});
return true;
}
}
$obj = new AsyncMySql();
$flag = $obj->execute(1, 'singwa-111112');
var_dump($flag).PHP_EOL;
echo "start".PHP_EOL;3.5 асинхронные повторы
3.5.1 подготовка окружающей среды
Предварительные условия для использования redis в swoole
редиссервисhiredisбиблиотека- Скомпилировать
swooleНужно присоединиться-включить-асинхронность-redis
Скомпилировать и установить хиредис
Использовать Redis Клиент, требуется установка hiredis Библиотека, Загрузка hiredis После исходного кода, выполнять
make -j sudo make install sudo ldconfig
Адрес для загрузки Hiredis
Включить асинхронный клиент redis
Скомпилировать свул Когда настроить Добавить в инструкцию --включить-асинхронный-повтор
[[email protected]z8wdxsujiec2oz swoole]# ./configure --with-php-config=/usr/local/php/bin/php-config --enable-async-redis make clean make -j sudo make install
Просмотр PHP Из свула Расширение: php -m Посмотреть нанятые Следует ли успешно скомпилировать и установить: php --ri swoole
3.5.2 проверка кода
$redisClient = new swoole_redis;// Swoole\Redis
$redisClient->connect('127.0.0.1', 6379, function(swoole_redis $redisClient, $result) {
echo "connect".PHP_EOL;
var_dump($result);
//Synchronize redis (New redis()) - > set ('key ', 2);
/*$redisClient->set('singwa_1', time(), function(swoole_redis $redisClient, $result) {
var_dump($result);
});*/
/*$redisClient->get('singwa_1', function(swoole_redis $redisClient, $result) {
var_dump($result);
$redisClient->close();
});*/
$redisClient->keys('*gw*', function(swoole_redis $redisClient, $result) {
var_dump($result);
$redisClient->close();
});
});
echo "start".PHP_EOL;Следующая статья:Переход от введения к практике (2): процесс, память и сотрудничество , swoole отлично поддерживает thinkphp5, реализацию асинхронного механизма распределения задач
Справочное руководство: Хань Тяньфэн рекомендует внедрить swoole для создания живой платформы для высокопроизводительных мероприятий
Оригинал: “https://developpaper.com/from-introduction-to-practice-of-swoole-i-php7-swoole-source-code-installation-playing-with-network-communication-engine-asynchronous-non-blocking-io-scenario/”