Gustavo Almeida
ReactPHP
$whois
CPU é rápida
I/O é lento
PHP ainda é essencialmente bloqueante.
I/O = Input/Output = E/S = entrada/saída de dados
Temos I/O em quase tudo : PDO, fopen, curl, BD
Relacionais, redes, email, APIs externas.
O processador que é o super-herói, fica ocioso.
CPU I/O
SÍNCRONO
ASSÍNCRONO
EXEMPLO - PIZZA
DELIVERY
request
request
response
BLOQUEANTE
Async em PHP
● pthreads
● popen()
● proc_open()
● pcntl_fork()
● socket_select()
● stream_select()
● stream_set_blocking()
● curl_multi_select()
Design Pattern React
programação reativa
reage a eventos
dispara callbacks
baseado no event loop
$loop->on(‘evento’,function(){
echo ‘reação feita’;
});
EVENT LOOP
requests
S.O.
filesystem
DB
email
EVENT LOOP
EVENT LOOP
requests
S.O.
filesystem
DB
email
while(true){
...
}
callbacks
Arquitetura - pedido / resposta
servidor
cliente / browser
cliente / browser
Arquitetura - pedido / resposta
servidor
cliente / browser
cliente / browser
Arquitetura - pedido / resposta
servidor
cliente / browser
cliente / browser
Tunel de mensagens (dados)
servidorcliente
event
loop
piscina
(poll)
tunel (stream/socket)
cliente
Tunel de mensagens (dados)
servidorcliente
event
loop
piscina
(poll)
tunel (stream/socket)
cliente
ReactPHP - “Hello World”
$loop = ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$http = new ReactHttpServer($socket,$loop);
$http->on(‘request’,function($req,$res){
$res->writeHead(200);
$res->end(‘hello world’);
});
$socket->listen(1234);
$loop->run();
composer require react/react
NodeJS x ReactPHP
https://philsturgeon.uk/php/2013/11/12/benchmarking-codswallop-nodejs-v-php/
http://www.hostingadvice.com/blog/comparing-node-js-vs-php-performance/
https://www.sitepoint.com/sitepoint-smackdown-php-vs-node-js/
$loop = ReactEventLoopFactory::create();
$socket = ReactSocketServer($loop);
$clients = [];
$i=0;
$socket->on('connection', function($connection) use ($clients, &$i){
$connection->id = ++$i;
$connection->write("Digite seu Nome : ");
$connection->on('data', function($msg) use ($clients, $connection){
if(empty($connection->apelido)){
$connection->apelido=$msg;
}else{
foreach($clients as $client){
if($client->id == $connection->id)
continue; }
$client->write(sprintf("[%s]: %s",$connection->apelido,$connection->msg));
}
}
});
$clients[]=$connection;
});
$socket->listen(1234);
$loop->run();
Chat 100% PHP em 22 linhas
Timers && Ticks
Timers
javascript
setInterval()
clearInterval()
setTimeout()
clearTimeout()
sleep() somente congela
o processamento.
Timers
javascript
setInterval()
clearInterval()
setTimeout()
clearTimeout()
ReactPHP
addPeriodicTimer()
cancelTimer()
addTimer()
isTimerActive()
sleep() somente congela
o processamento.
EVENT LOOP
$loop->addPeriodicTimer(10, function(){
getTweets();
});
Promises
Promessa é uma abstração para programação assíncrona, que recebe algum
input (dados) e retorna uma promessa do output (resultado).
Um sistema baseado em callbacks, recebe um input e um callback (função), que
é executado passando algum output.
Promises
if(play($resultado)){
...
function play($param){
return conta($param);
}
function conta($param){
return alguma_conta($param);
}
Callback
$um->play(function ($dois)){
$dois->play(function ($tres)){
$tres->play(function ($quatro)){
$quatro->get(function($resultado)){
echo $resultado;
});
});
});
});
Callback Hell
$um->play(function ($dois)){
$dois->play(function ($tres)){
$tres->play(function ($quatro)){
$quatro->get(function($resultado)){
echo $resultado;
});
});
});
});
Deferred && Promises
$promise->then();
$promise->done();
$promise->otherwise();
$promise->always();
$deferred->resolve();
$deferred->reject();
● unfulfilled (waiting)
● fulfilled (resolved)
● rejected (failed)
$deferred = new ReactPromiseDeferred();
$promise = $deferred->promise();
$deferred
trabalho não finalizado
$promise
resultado não conhecido
tem
$deferred
trabalho não finalizado
$promise
resultado não conhecido
$callbacks
executados
estados
tem
tem
tem
$deferred
trabalho não finalizado
$promise
resultado não conhecido
$callbacks
executados
estados
tem
tem
tem
de acordo com ● unfulfilled (waiting)
● fulfilled (resolved)
● rejected (failed)
Encadeamento de Promises
$deferred->promise()->then(f(){})->then(f(){})->then(f(){}) ...
Encadeamento de Promises
$deferred->promise()->then(f(){})->then(f(){})->then(f(){}) ...
Encadeamento de Promises
$promises = [ ];
foreach($hostnames as $hostname){
$promises[ ]=$dns->resolve($hostname)->then(
function(){
…})-> ...
}
ReactPromiseall($promises)->then( function(){ …})-> ...
Streams && Sockets
stream
UDP, video, telefonia
socket
three-way-handshake
Streams && Sockets
Programa A Programa Bfluxo de dados
- Endereco
- Porta
● Readable
● Writeable
● Duplex
$loop = ReactEventLoopFactory::create();
$client = new ReactHttpClientClient($loop);
$file = new ReactStreamWritableResourceStream(fopen('sample.mp4', 'w'), $loop);
$request = $client->request('GET', 'http://www.sample-videos.com/videos/filme.mp4');
$request->on('response', function (ReactHttpClientResponse $response) use ($file) {
$size = $response->getHeaders()['Content-Length'];
$currentSize = 0;
$progress = new ReactStreamThroughStream();
$progress->on('data', function($data) use ($size, &$currentSize){
$currentSize += strlen($data);
echo "033[1A", "Downloading: ", number_format($currentSize / $size * 100), "%n";
});
$response->pipe($progress)->pipe($file);
});
$request->end();
$loop->run();
Informação em tempo real - Exibindo o progresso em % do download de um arquivo
var conn = new WebSocket('ws://127.0.0.1:1337');
conn.onmessage = function(e) { console.log(e.data); };
conn.onopen = function(e) { conn.send(Olá Mundo!'); };
$loop = ReactEventLoopFactory::create();
$socket = new ReactSocketServer('127.0.0.1:1337', $loop);
$socket->on('connection', function (ConnectionInterface $conn) {
Concatenando com pipe()
$loop = ReactEventLoopFactory::create();
$origem = new ReactStreamStream(fopen('log.txt', 'r+'), $loop);
$destino = new ReactStreamStream(fopen('destino.txt', 'w+'), $loop);
$origem->pipe($maiusculas)->pipe($blackList)-> ... ->pipe($destino);
$loop->run();
conceito parecido no linux ( | )
# ls | sort -r | tee arquivo.txt | wc -l
f() f()
???
PHP8
github: lga37
slideshare: lga33
br.linkedin.com/in/lga37
$loop->stop();

ReactPHP && programacao assincrona em PHP