SlideShare una empresa de Scribd logo
1 de 53
Descargar para leer sin conexión
Asynchroniczny PHP
& komunikacja czasu
rzeczywistego z
wykorzystaniem
websocketów
who am i
Nazywam się Łukasz
Adamczewski
Pracuje w firmie Polcode jako
Starszy Programista PHP
Szukaj mnie na @lukeadamczewski
- czyli wasz język tego nie potrafi
CPU IO CPU
czas
IO
Model typowej aplikacji
W czym problem?
Model typowej aplikacji
CPU IO CPU
czas
IO
asynchroniczna instrukcja
CPU
Model non-blocking IO
IO
IO
CPU
IO
CPU
CZAS
różnyczaswykonywania
IO
oczekiwanie na koniec
poprzedniego zadania
Słów kilka o czasach dostępu czyli IO vs CPU
http://norvig.com/21-days.html#answers
fetch from L1 cache memory 0.5 nanosec
fetch from L2 cache memory 7 nanosec
fetch from main memory 100 nanosec
send 2K bytes over 1Gbps network 20,000 nanosec
read 1MB sequentially from memory 0,25 ms = 250,000 ns
Read 1 MB sequentially from SSD* 1 ms
Disk seek 10 ms
Read 1 MB sequentially from disk 20 ms
send packet US to Europe and back 150 ms
* Assuming ~1GB/sec SSD
getUser(432, function (user) {
console.log(user.name);
});
console.log('Done');
Typowy node.js
getUser(432, function (user) {
console.log(user.name);
});
console.log('Done');1
Typowy node.js
getUser(432, function (user) {
console.log(user.name);
});
console.log('Done');1
2
Typowy node.js
Node.JS - webserver “hello world”
var http = require('http');
var server = new http.Server();
server.on('request', function (req, res) {
res.writeHead(
200,
{'Content-Type':'text/plain'}
);
res.end('Hello World');
});
server.listen(8000, '127.0.0.1');
Node.JS - webserver “hello world”
var http = require('http');
var server = new http.Server();
server.on('request', function (req, res) {
res.writeHead(
200,
{'Content-Type':'text/plain'}
);
res.end('Hello World');
});
server.listen(8000, '127.0.0.1');
oczekiwanie na zdarzenie request
kod obsługi zdarzenia wysyłający
odpowiednie nagłówki do klienta HTTP
oraz wysyłający odpowiednią
wiadomość
Node.JS - webserver “hello world”
var http = require('http');
var server = new http.Server();
server.on('request', function (req, res) {
res.writeHead(
200,
{'Content-Type':'text/plain'}
);
res.end('Hello World');
});
server.listen(8000, '127.0.0.1');
oczekiwanie na zdarzenie request
kod obsługi zdarzenia wysyłający
odpowiednie nagłówki do klienta HTTP
oraz wysyłający odpowiednią
wiadomość
C10K problem
10k połączeń na jednym rdzeniu
Node.JS - webserver “hello world”
var http = require('http');
var server = new http.Server();
server.on('request', function (req, res) {
res.writeHead(
200,
{'Content-Type':'text/plain'}
);
res.end('Hello World');
});
server.listen(8000, '127.0.0.1');
oczekiwanie na zdarzenie request
kod obsługi zdarzenia wysyłający
odpowiednie nagłówki do klienta HTTP
oraz wysyłający odpowiednią
wiadomość
C10K problem
10k połączeń na jednym rdzeniu
Zróbmy to
w PHP!bo w czym problem?
<?php
$server = stream_socket_server('tcp://127.0.0.1:8000');
while ($conn = stream_socket_accept($server, -1)) {
fwrite($conn, "HTTP/1.1 200 OKrn");
fwrite($conn, "Content-Length: 3rnrn");
fwrite($conn, "Hi PHPersn");
fclose($conn);
}
$ curl 127.0.0.1:8000 -v
> GET / HTTP/1.1
> Host: 127.0.0.1:8000
< HTTP/1.1 200 OK
Hi PHPers
<?php
$server = stream_socket_server('tcp://127.0.0.1:8000');
while ($conn = stream_socket_accept($server, -1)) {
fwrite($conn, "HTTP/1.1 200 OKrn");
fwrite($conn, "Content-Length: 3rnrn");
fwrite($conn, "Hi PHPersn");
fclose($conn);
}
BLOCKING
IO
<?php
$server = stream_socket_server('tcp://127.0.0.1:8000');
while ($conn = stream_socket_accept($server, -1)) {
fwrite($conn, "HTTP/1.1 200 OKrn");
fwrite($conn, "Content-Length: 3rnrn");
fwrite($conn, "Hi PHPersn");
fclose($conn);
}
BLOCKING
IO
NON-BLOCKING
IO
// If mode is 0, the given stream will be switched to non-blocking mode
bool stream_set_blocking ( resource $stream , int $mode )
int stream_select ( array &$read , array &$write , array &$except , int
$tv_sec [, int $tv_usec = 0 ] )
$readable = $read ?: null;
$writable = $write ?: null;
$except = null;
if (stream_select($readable, $writable, $except, 1)) {
if ($readable) {
foreach ($readable as $stream) { /* code */ }
}
if ($writable) {
foreach ($writable as $stream) { /* code */ }
}
}
Pooling IO
tablica streamów do odczytu
tablica streamów do zapisu
streamy “faworyzowane”
Pooling IOPooling IO
$readable = $read ?: null;
$writable = $write ?: null;
$except = null;
if (stream_select($readable, $writable, $except, 1)) {
if ($readable) {
foreach ($readable as $stream) { /* code */ }
}
if ($writable) {
foreach ($writable as $stream) { /* code */ }
}
}
EVENT
LOOPCZYLI MOŻNA LEPIEJ
EVENT LOOP
➜ Zarządzanie streamami
➜ Ustawianie timerów jednorazowych i cyklicznych
➜ Ustawianie nextTicków i futureTicków
➜ Maksymalna czas zwłoki (timeout) może być zdefiniowany
➜ Jeżeli nie ma dalszych ticków, timerów lub streamów do obsłużenia -
event loop kończy pracę
Event Loop:
Istnieje kilka implementacji z docelowymi backendami:
● StreamSelectLoop - stream_select
● LibEventLoop - libevent pecl extension
● LibEvLoop - libev pecl extension (najszybszy)
● może kiedyś LibUV :)
Demultiplexer:
oczekuje na eventy dla zasobów np.
nowe połączenie i powiadamia
dispatcher, po czym przechodzi do
dalszego nasłuchiwania.
Dispatcher:
Komponent służący do rejestracji obsługi
zdarzeń. Odbiera synchronicznie event z
demultiplexera i wybiera właściwy event
handler, który następnie uruchamia.
Obsługa zdarzeń:
Event Handler który obsługuje
przekierowane do niego zdarzenie. Jest
to po prostu jeden ze zdefiniowanych
wcześniej callbacków.
Zasoby:
Czyli tutaj mamy wszystkie streamy które
chcemy obsługiwać. Mogą to być także
procesy czy np. uchwyty do plików.
Hello World Again
Instalacja z wykorzystaniem composera
curl -sS https://getcomposer.org/installer | php
php composer.phar require react/react
require 'vendor/autoload.php';
$loop = ReactEventLoopFactory::create();
$socket = new ReactSocketServer($loop);
$http = new ReactHttpServer($socket, $loop);
$http->on('request', function ($request, $response) {
$response->writeHead(200, ['Content-Type' =>
'text/plain']);
$response->end("Hi Phpersn");
});
$socket->listen(8000);
$loop->run();
Ekosystem
EVENT LOOP
STREAM
TICKS
SOCKET
HTTP
TIMER
CHILD PROCESSFILESYSTEM
PROMISES
EVENT LOOP
STREAM
TICKS
SOCKET
HTTP
TIMER
CHILD PROCESSFILESYSTEM
PROMISES
Ticki
umożliwiają wykonywanie określonych funkcji w ramach Event Loopa. Dzielą się na $loop-
>nextTick($callback) i $loop->futureTick($callback) .
Pierwszy jest wykonywany zawsze na początku każdej iteracji loopa, wykonywanie drugiego
jest zawsze oddelegowane jako ostatnia operacja w ramach iteracji.
Hint: zakolejkowane futureTicki nie będą wykonywane jeśli Event Loop nie ma więcej
zadań. NextTicki uzupełniają Event Loop nowymi zadaniami.
EVENT LOOP
STREAM
TICKS
SOCKET
HTTP
TIMER
CHILD PROCESSFILESYSTEM
PROMISES
Funkcja odmierzania czasu wykonywana w ramach Event Loop w kolejności zaraz po nextTicku.
● $loop->addTimer- jednorazowe wykonanie funkcji po upływie czasu (jak setTimeout)
● $loop->addPeriodicTimer- wykonuje funkcje cyklicznie (jak setInterval)
● $loop->cancelTimer - zatrzymje timer
● $loop->isTimerActive- sprawdza stan działania timera
Hint: nie polegaj na czasie odmierzanym przez timery w 100% ponieważ operacje przetwarzane w
Event Loop mogą zablokować je na jakiś czas wynikający z bieżących działań.
STREAM
SOCKET
HTTP
CHILD PROCESSFILESYSTEM
PROMISES
● Opakowuje natywny zasób stream.
● Rejestrowane w ramach Event Loop’a.
● Stream do odczytu i zapisu (ReadableStream / WriteableStream)
● Potkowość (ang. pipeline). WriteableStream może być ze sobą łączone, więc wyjście
jednego jest wejściem drugiego.
● Dane wczytywane / zapisywane do streamów są buforowane
Klasy Funkcjonalne:
CompositeStream- łączy streamy do odczytu i zapisu łącząc obydwie funkcjonalności
ThroughStream- umożliwia modyfikacje danch które stream zawiera - filtrowanie.
BufferedSink - konwertuje WriteableStreamdo Promise
STREAM
STREAM
SOCKET
HTTP
CHILD PROCESSFILESYSTEM
PROMISES
Dla funkcji asynchronicznych umożliwia natychmiastowy zwrot wartości, a raczej pewnej
zaliczki tej wartości.
Przykład - zamiana hosta na ip:
$factory = new ReactDnsResolverFactory();
$dns = $factory->create('8.8.8.8', $loop);
$dns->resolve('igor.io')->then(function ($ip) {
echo "Host: $ipn";
});
PROMISE
STREAM
SOCKET
HTTP
CHILD PROCESSFILESYSTEM
PROMISES
Komponent sieciowy umożliwiający tworzenie serwerów nasłuchujących nowych połączeń
oraz przetwarzających dane połączonych klientów.
$socket = new ReactSocketServer($loop);
$socket->on('connection', function ($conn) {
$conn->on('data', function ($data, $conn) {
$conn->write($data);
});
});
$socket->listen(1337);
SOCKET
Websockety
Komunikacja w czasie rzeczywistym
Websockety - zalety
➜ Wsparcie we wszystkich wiodących
przeglądarkach (> IE8)
➜ Dwukierunkowość komunikacji
➜ Niezależnie wysyłanie wiadomości
➜ Protokół oparty na HTTP
➜ Niewielki rozmiar pojedynczego pakietu
danych
WebsocketAPI - interfejs kliencki JavaScript
var websocket = new WebSocket('ws://localhost:8000' );
websocket.onopen = function(evt) {};
websocket.onclose = function(evt) {};
websocket.onmessage = function(evt) {};
websocket.onerror = function(evt) {};
Ratchet - WebSockets for PHP
class WS implements MessageComponentInterface {
function onOpen(ConnectionInterface $conn) {}
function onClose(ConnectionInterface $conn) {}
function onError(ConnectionInterface $conn, Exception $e) {}
function onMessage(ConnectionInterface $from, $msg) {
$from->send($msg);
}
}
$server = IoServer::factory(
new HttpServer(new WsServer(new WS())),
3000
);
$server->run();
The Web Application Messaging Protocol
The Bigger The Better
➜ Remote Procedure Calls (RPC)
➜ Publish & Subscribe
➜ Autobahn.JS
➜ integracja ZeroMQ
➜ integracja Redis
Autobahn.JS?
// dla wersji AUTOBAHNJS_VERSION="0.7.1"
var session = new ab.Session(
"ws://127.0.0.1:3000",
function () {
// zostaliśmy połączeni
},
function () {
// zostaliśmy rozłączeni
},
{
'skipSubprotocolCheck': true,
'maxRetries': 5,
'retryDelay': 2000
}
);
session.subscribe("http://phpers.pl/event/message", callback);
class WAMP implements RatchetWampWampServerInterface {
public function onPublish(ConnectionInterface $conn, $topic, $event, array
$exclude, array $eligible) {}
public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {}
public function onSubscribe(ConnectionInterface $conn, $topic) {}
public function onUnSubscribe(ConnectionInterface $conn, $topic) {}
public function onOpen(ConnectionInterface $conn) {}
public function onClose(ConnectionInterface $conn) {}
public function onError(ConnectionInterface $conn, Exception $e) {}
}
$server = RatchetServerIoServer::factory(
new HttpServer(new WsServer(new WampServer(new WAMP()))),
3000
);
$server->run();
Ratchet + WAMP
$loop = ReactEventLoopFactory::create();
$pusher = new WAMP;
$context = new ReactZMQContext($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555');
$pull->on('message', array($pusher, 'onQueueAdded'));
$socket = new ReactSocketServer($loop);
$socket->listen(3000, '0.0.0.0');
$webServer = new IoServer(
new HttpServer(new WsServer(new WampServer($pusher))),
$socket
);
$loop->run();
ZeroMQ + Ratchet
ZeroMQ + Ratchet
$loop = ReactEventLoopFactory::create();
$pusher = new WAMP;
$context = new ReactZMQContext($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555');
$pull->on('message', array($pusher, 'onQueueAdded'));
$socket = new ReactSocketServer($loop);
$socket->listen(3000, '0.0.0.0');
$webServer = new IoServer(
new HttpServer(new WsServer(new WampServer($pusher))),
$socket
);
$loop->run();
$context = new ZMQContext();
$socket = $context->getSocket(
ZMQ::SOCKET_PUSH,
'websocket'
);
$socket->connect('tcp://127.0.0.1:5555');
$socket->send($payloadAsJSON);
ZeroMQ + Ratchet
$loop = ReactEventLoopFactory::create();
$pusher = new WAMP;
$context = new ReactZMQContext($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555');
$pull->on('message', array($pusher, 'onQueueAdded'));
$socket = new ReactSocketServer($loop);
$socket->listen(3000, '0.0.0.0');
$webServer = new IoServer(
new HttpServer(new WsServer(new WampServer($pusher))),
$socket
);
$loop->run();
$context = new ZMQContext();
$socket = $context->getSocket(
ZMQ::SOCKET_PUSH,
'websocket'
);
$socket->connect('tcp://127.0.0.1:5555');
$socket->send($payloadAsJSON);
public function onQueueAdded($payload) {
$payloadData = json_decode($payload, true);
// dalsze przetwarzanie
}
MAO?
➜ WAMP2
➜ voryx/Thruway (kompatybilny z nowym
Autobahn.JS)
➜ bixuehujin/reactphp-mysql
➜ DNode
➜ STOMP
➜ AR.Drone
➜ Whois
➜ Childprocess
Koniec!
Macie pytania?
Odniesienia i inspiracje
➜ http://blog.wyrihaximus.net/categories/reactphp/
➜ Presentation theme - SlidesCarnival
➜ Zdjęcia - Death to the Stock Photo
➜ http://www.slideshare.
net/SteveRhoades2/asynchronous-php-and-realtime-
messaging
➜ https://speakerdeck.com/jmikola/async-php-with-react
➜ https://speakerdeck.com/igorw/react-phpnw

Más contenido relacionado

La actualidad más candente

4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...PROIDEA
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Maciek Próchniak
 
Wstęp do projektowania usług internetowych: część 1 - rest
Wstęp do projektowania usług internetowych: część 1 - restWstęp do projektowania usług internetowych: część 1 - rest
Wstęp do projektowania usług internetowych: część 1 - restLukas Lesniewski
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Natalia Stanko
 
ansible kmonticolo bezlogo
ansible kmonticolo bezlogoansible kmonticolo bezlogo
ansible kmonticolo bezlogoKamil Monticolo
 
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)PROIDEA
 
Prezentacja Jabber
Prezentacja JabberPrezentacja Jabber
Prezentacja Jabberbm9ib2r5
 
HTTP od zera do bohatera
HTTP od zera do bohateraHTTP od zera do bohatera
HTTP od zera do bohateraHordeTechnology
 
Sekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerSekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerKamil Grabowski
 
3Camp Tech 2016/11/15 - Front-end tooling: package managers
3Camp Tech 2016/11/15 - Front-end tooling: package managers3Camp Tech 2016/11/15 - Front-end tooling: package managers
3Camp Tech 2016/11/15 - Front-end tooling: package managersMichał Michalczuk
 

La actualidad más candente (17)

4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
4Developers 2015: Szybciej niż Struś Pędziwiatr - WebSockets w aplikacjach we...
 
Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010Camel-Drools - Javarsovia 2010
Camel-Drools - Javarsovia 2010
 
Po co nam RSocket?
Po co nam RSocket?Po co nam RSocket?
Po co nam RSocket?
 
Wstęp do projektowania usług internetowych: część 1 - rest
Wstęp do projektowania usług internetowych: część 1 - restWstęp do projektowania usług internetowych: część 1 - rest
Wstęp do projektowania usług internetowych: część 1 - rest
 
Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010Ruby, Ruby on Rails 2010
Ruby, Ruby on Rails 2010
 
ansible kmonticolo bezlogo
ansible kmonticolo bezlogoansible kmonticolo bezlogo
ansible kmonticolo bezlogo
 
GlusterFS
GlusterFSGlusterFS
GlusterFS
 
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)
PLNOG 7: Łukasz Bromirski - BGP Blackholing PL v2.0 re(boot|reload)
 
Prezentacja Jabber
Prezentacja JabberPrezentacja Jabber
Prezentacja Jabber
 
HTTP od zera do bohatera
HTTP od zera do bohateraHTTP od zera do bohatera
HTTP od zera do bohatera
 
WordCamp Gdynia 2016
WordCamp Gdynia 2016WordCamp Gdynia 2016
WordCamp Gdynia 2016
 
Sekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu DockerSekrety magicznego ogrodu Docker
Sekrety magicznego ogrodu Docker
 
CruiseControl.rb
CruiseControl.rbCruiseControl.rb
CruiseControl.rb
 
Jaki hosting pod wordpressa
Jaki hosting pod wordpressaJaki hosting pod wordpressa
Jaki hosting pod wordpressa
 
Android i REST
Android i RESTAndroid i REST
Android i REST
 
Optymalizacja serwisow internetowych - Filestube
Optymalizacja serwisow internetowych - FilestubeOptymalizacja serwisow internetowych - Filestube
Optymalizacja serwisow internetowych - Filestube
 
3Camp Tech 2016/11/15 - Front-end tooling: package managers
3Camp Tech 2016/11/15 - Front-end tooling: package managers3Camp Tech 2016/11/15 - Front-end tooling: package managers
3Camp Tech 2016/11/15 - Front-end tooling: package managers
 

Destacado

REST, Web Sockets, Server-sent Events
REST, Web Sockets, Server-sent EventsREST, Web Sockets, Server-sent Events
REST, Web Sockets, Server-sent EventsIvano Malavolta
 
Symfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingSymfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingWojciech Ciołko
 
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!Masoud Kalali
 
Oracle Database 12c Attack Vectors
Oracle Database 12c Attack VectorsOracle Database 12c Attack Vectors
Oracle Database 12c Attack VectorsMartin Toshev
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)Javier Eguiluz
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golangBo-Yi Wu
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricksJavier Eguiluz
 

Destacado (10)

REST, Web Sockets, Server-sent Events
REST, Web Sockets, Server-sent EventsREST, Web Sockets, Server-sent Events
REST, Web Sockets, Server-sent Events
 
Django Celery
Django Celery Django Celery
Django Celery
 
Symfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processingSymfony bundle fo asynchronous job processing
Symfony bundle fo asynchronous job processing
 
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!
Server Sent Events, Async Servlet, Web Sockets and JSON; born to work together!
 
Oracle Database 12c Attack Vectors
Oracle Database 12c Attack VectorsOracle Database 12c Attack Vectors
Oracle Database 12c Attack Vectors
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
 
Golang for OO Programmers
Golang for OO ProgrammersGolang for OO Programmers
Golang for OO Programmers
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
 
Write microservice in golang
Write microservice in golangWrite microservice in golang
Write microservice in golang
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 

Similar a Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw

PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPROIDEA
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegroallegro.tech
 
Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Laravel Poland MeetUp
 
TV i video w Internecie
TV i video w InternecieTV i video w Internecie
TV i video w InternecieDivante
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...Tomasz Kopacz
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Codesushi.co (CODESUSHI LLC)
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajnościmagda3695
 
OpenSSH Kombajn z Wodotryskiem
OpenSSH Kombajn z WodotryskiemOpenSSH Kombajn z Wodotryskiem
OpenSSH Kombajn z Wodotryskiemlinuxcamp
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...The Software House
 
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaModsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaLeszek Mi?
 
infraxstructure: Robert Mroczkowski "Maszyny się uczą - admińskie rozmówki p...
infraxstructure: Robert Mroczkowski  "Maszyny się uczą - admińskie rozmówki p...infraxstructure: Robert Mroczkowski  "Maszyny się uczą - admińskie rozmówki p...
infraxstructure: Robert Mroczkowski "Maszyny się uczą - admińskie rozmówki p...PROIDEA
 
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PROIDEA
 
Debugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugDebugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugXSolve
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?The Software House
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaMaciej Ziarko
 

Similar a Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw (20)

PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
 
Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?Swoole w PHP. Czy to ma sens?
Swoole w PHP. Czy to ma sens?
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
 
Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)Cykl życia zapytania HTTP (pod maską)
Cykl życia zapytania HTTP (pod maską)
 
TV i video w Internecie
TV i video w InternecieTV i video w Internecie
TV i video w Internecie
 
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...Mts 2013   tomasz kopacz - windows 8, office 365, workflow manager, windows a...
Mts 2013 tomasz kopacz - windows 8, office 365, workflow manager, windows a...
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
Tomasz Kopacz MTS 2012 Wind RT w Windows 8 i tzw aplikacje lob (line of busin...
 
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
Warsztaty: Podstawy PHP - część 2 - omówienie składni języka PHP (wersja 7)
 
Info meet pomiary wydajności
Info meet pomiary wydajnościInfo meet pomiary wydajności
Info meet pomiary wydajności
 
OpenSSH Kombajn z Wodotryskiem
OpenSSH Kombajn z WodotryskiemOpenSSH Kombajn z Wodotryskiem
OpenSSH Kombajn z Wodotryskiem
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
“Dziesięć serwerów poproszę!“, czyli co może Ci zaoferować definiowanie infra...
 
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-PolskaModsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
Modsecurity-czy-Twoj-WAF-to-potrafi-Leszek-Mis-Linux-Polska
 
DSL - DYI
DSL - DYIDSL - DYI
DSL - DYI
 
infraxstructure: Robert Mroczkowski "Maszyny się uczą - admińskie rozmówki p...
infraxstructure: Robert Mroczkowski  "Maszyny się uczą - admińskie rozmówki p...infraxstructure: Robert Mroczkowski  "Maszyny się uczą - admińskie rozmówki p...
infraxstructure: Robert Mroczkowski "Maszyny się uczą - admińskie rozmówki p...
 
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
PLNOG22 - Piotr Stolarek - Bezpieczeństwo użytkowania platform usługowych Tel...
 
Debugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebugDebugowanie skryptow php za pomoca xdebug
Debugowanie skryptow php za pomoca xdebug
 
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
Monitoring systemu. Dlaczego mój kardiolog jest bogatym człowiekiem?
 
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarkaThymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
Thymeleaf - szablony, które bez przetworzenia zrozumie twoja przeglądarka
 

Asynchroniczny PHP i komunikacja czasu rzeczywistego z wykorzystaniem websocketw

  • 1. Asynchroniczny PHP & komunikacja czasu rzeczywistego z wykorzystaniem websocketów
  • 2. who am i Nazywam się Łukasz Adamczewski Pracuje w firmie Polcode jako Starszy Programista PHP Szukaj mnie na @lukeadamczewski
  • 3. - czyli wasz język tego nie potrafi
  • 4. CPU IO CPU czas IO Model typowej aplikacji
  • 5. W czym problem? Model typowej aplikacji CPU IO CPU czas IO
  • 6. asynchroniczna instrukcja CPU Model non-blocking IO IO IO CPU IO CPU CZAS różnyczaswykonywania IO oczekiwanie na koniec poprzedniego zadania
  • 7. Słów kilka o czasach dostępu czyli IO vs CPU http://norvig.com/21-days.html#answers fetch from L1 cache memory 0.5 nanosec fetch from L2 cache memory 7 nanosec fetch from main memory 100 nanosec send 2K bytes over 1Gbps network 20,000 nanosec read 1MB sequentially from memory 0,25 ms = 250,000 ns Read 1 MB sequentially from SSD* 1 ms Disk seek 10 ms Read 1 MB sequentially from disk 20 ms send packet US to Europe and back 150 ms * Assuming ~1GB/sec SSD
  • 8. getUser(432, function (user) { console.log(user.name); }); console.log('Done'); Typowy node.js
  • 9. getUser(432, function (user) { console.log(user.name); }); console.log('Done');1 Typowy node.js
  • 10. getUser(432, function (user) { console.log(user.name); }); console.log('Done');1 2 Typowy node.js
  • 11. Node.JS - webserver “hello world” var http = require('http'); var server = new http.Server(); server.on('request', function (req, res) { res.writeHead( 200, {'Content-Type':'text/plain'} ); res.end('Hello World'); }); server.listen(8000, '127.0.0.1');
  • 12. Node.JS - webserver “hello world” var http = require('http'); var server = new http.Server(); server.on('request', function (req, res) { res.writeHead( 200, {'Content-Type':'text/plain'} ); res.end('Hello World'); }); server.listen(8000, '127.0.0.1'); oczekiwanie na zdarzenie request kod obsługi zdarzenia wysyłający odpowiednie nagłówki do klienta HTTP oraz wysyłający odpowiednią wiadomość
  • 13. Node.JS - webserver “hello world” var http = require('http'); var server = new http.Server(); server.on('request', function (req, res) { res.writeHead( 200, {'Content-Type':'text/plain'} ); res.end('Hello World'); }); server.listen(8000, '127.0.0.1'); oczekiwanie na zdarzenie request kod obsługi zdarzenia wysyłający odpowiednie nagłówki do klienta HTTP oraz wysyłający odpowiednią wiadomość C10K problem 10k połączeń na jednym rdzeniu
  • 14. Node.JS - webserver “hello world” var http = require('http'); var server = new http.Server(); server.on('request', function (req, res) { res.writeHead( 200, {'Content-Type':'text/plain'} ); res.end('Hello World'); }); server.listen(8000, '127.0.0.1'); oczekiwanie na zdarzenie request kod obsługi zdarzenia wysyłający odpowiednie nagłówki do klienta HTTP oraz wysyłający odpowiednią wiadomość C10K problem 10k połączeń na jednym rdzeniu
  • 15. Zróbmy to w PHP!bo w czym problem?
  • 16. <?php $server = stream_socket_server('tcp://127.0.0.1:8000'); while ($conn = stream_socket_accept($server, -1)) { fwrite($conn, "HTTP/1.1 200 OKrn"); fwrite($conn, "Content-Length: 3rnrn"); fwrite($conn, "Hi PHPersn"); fclose($conn); } $ curl 127.0.0.1:8000 -v > GET / HTTP/1.1 > Host: 127.0.0.1:8000 < HTTP/1.1 200 OK Hi PHPers
  • 17. <?php $server = stream_socket_server('tcp://127.0.0.1:8000'); while ($conn = stream_socket_accept($server, -1)) { fwrite($conn, "HTTP/1.1 200 OKrn"); fwrite($conn, "Content-Length: 3rnrn"); fwrite($conn, "Hi PHPersn"); fclose($conn); } BLOCKING IO
  • 18. <?php $server = stream_socket_server('tcp://127.0.0.1:8000'); while ($conn = stream_socket_accept($server, -1)) { fwrite($conn, "HTTP/1.1 200 OKrn"); fwrite($conn, "Content-Length: 3rnrn"); fwrite($conn, "Hi PHPersn"); fclose($conn); } BLOCKING IO NON-BLOCKING IO // If mode is 0, the given stream will be switched to non-blocking mode bool stream_set_blocking ( resource $stream , int $mode ) int stream_select ( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] )
  • 19. $readable = $read ?: null; $writable = $write ?: null; $except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { /* code */ } } if ($writable) { foreach ($writable as $stream) { /* code */ } } } Pooling IO
  • 20. tablica streamów do odczytu tablica streamów do zapisu streamy “faworyzowane” Pooling IOPooling IO $readable = $read ?: null; $writable = $write ?: null; $except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { /* code */ } } if ($writable) { foreach ($writable as $stream) { /* code */ } } }
  • 22. EVENT LOOP ➜ Zarządzanie streamami ➜ Ustawianie timerów jednorazowych i cyklicznych ➜ Ustawianie nextTicków i futureTicków ➜ Maksymalna czas zwłoki (timeout) może być zdefiniowany ➜ Jeżeli nie ma dalszych ticków, timerów lub streamów do obsłużenia - event loop kończy pracę
  • 23.
  • 24.
  • 25. Event Loop: Istnieje kilka implementacji z docelowymi backendami: ● StreamSelectLoop - stream_select ● LibEventLoop - libevent pecl extension ● LibEvLoop - libev pecl extension (najszybszy) ● może kiedyś LibUV :)
  • 26. Demultiplexer: oczekuje na eventy dla zasobów np. nowe połączenie i powiadamia dispatcher, po czym przechodzi do dalszego nasłuchiwania.
  • 27. Dispatcher: Komponent służący do rejestracji obsługi zdarzeń. Odbiera synchronicznie event z demultiplexera i wybiera właściwy event handler, który następnie uruchamia.
  • 28. Obsługa zdarzeń: Event Handler który obsługuje przekierowane do niego zdarzenie. Jest to po prostu jeden ze zdefiniowanych wcześniej callbacków.
  • 29. Zasoby: Czyli tutaj mamy wszystkie streamy które chcemy obsługiwać. Mogą to być także procesy czy np. uchwyty do plików.
  • 31. Instalacja z wykorzystaniem composera curl -sS https://getcomposer.org/installer | php php composer.phar require react/react
  • 32. require 'vendor/autoload.php'; $loop = ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $http = new ReactHttpServer($socket, $loop); $http->on('request', function ($request, $response) { $response->writeHead(200, ['Content-Type' => 'text/plain']); $response->end("Hi Phpersn"); }); $socket->listen(8000); $loop->run();
  • 34. EVENT LOOP STREAM TICKS SOCKET HTTP TIMER CHILD PROCESSFILESYSTEM PROMISES Ticki umożliwiają wykonywanie określonych funkcji w ramach Event Loopa. Dzielą się na $loop- >nextTick($callback) i $loop->futureTick($callback) . Pierwszy jest wykonywany zawsze na początku każdej iteracji loopa, wykonywanie drugiego jest zawsze oddelegowane jako ostatnia operacja w ramach iteracji. Hint: zakolejkowane futureTicki nie będą wykonywane jeśli Event Loop nie ma więcej zadań. NextTicki uzupełniają Event Loop nowymi zadaniami.
  • 35. EVENT LOOP STREAM TICKS SOCKET HTTP TIMER CHILD PROCESSFILESYSTEM PROMISES Funkcja odmierzania czasu wykonywana w ramach Event Loop w kolejności zaraz po nextTicku. ● $loop->addTimer- jednorazowe wykonanie funkcji po upływie czasu (jak setTimeout) ● $loop->addPeriodicTimer- wykonuje funkcje cyklicznie (jak setInterval) ● $loop->cancelTimer - zatrzymje timer ● $loop->isTimerActive- sprawdza stan działania timera Hint: nie polegaj na czasie odmierzanym przez timery w 100% ponieważ operacje przetwarzane w Event Loop mogą zablokować je na jakiś czas wynikający z bieżących działań.
  • 36. STREAM SOCKET HTTP CHILD PROCESSFILESYSTEM PROMISES ● Opakowuje natywny zasób stream. ● Rejestrowane w ramach Event Loop’a. ● Stream do odczytu i zapisu (ReadableStream / WriteableStream) ● Potkowość (ang. pipeline). WriteableStream może być ze sobą łączone, więc wyjście jednego jest wejściem drugiego. ● Dane wczytywane / zapisywane do streamów są buforowane Klasy Funkcjonalne: CompositeStream- łączy streamy do odczytu i zapisu łącząc obydwie funkcjonalności ThroughStream- umożliwia modyfikacje danch które stream zawiera - filtrowanie. BufferedSink - konwertuje WriteableStreamdo Promise STREAM
  • 37. STREAM SOCKET HTTP CHILD PROCESSFILESYSTEM PROMISES Dla funkcji asynchronicznych umożliwia natychmiastowy zwrot wartości, a raczej pewnej zaliczki tej wartości. Przykład - zamiana hosta na ip: $factory = new ReactDnsResolverFactory(); $dns = $factory->create('8.8.8.8', $loop); $dns->resolve('igor.io')->then(function ($ip) { echo "Host: $ipn"; }); PROMISE
  • 38. STREAM SOCKET HTTP CHILD PROCESSFILESYSTEM PROMISES Komponent sieciowy umożliwiający tworzenie serwerów nasłuchujących nowych połączeń oraz przetwarzających dane połączonych klientów. $socket = new ReactSocketServer($loop); $socket->on('connection', function ($conn) { $conn->on('data', function ($data, $conn) { $conn->write($data); }); }); $socket->listen(1337); SOCKET
  • 40. Websockety - zalety ➜ Wsparcie we wszystkich wiodących przeglądarkach (> IE8) ➜ Dwukierunkowość komunikacji ➜ Niezależnie wysyłanie wiadomości ➜ Protokół oparty na HTTP ➜ Niewielki rozmiar pojedynczego pakietu danych
  • 41. WebsocketAPI - interfejs kliencki JavaScript var websocket = new WebSocket('ws://localhost:8000' ); websocket.onopen = function(evt) {}; websocket.onclose = function(evt) {}; websocket.onmessage = function(evt) {}; websocket.onerror = function(evt) {};
  • 43. class WS implements MessageComponentInterface { function onOpen(ConnectionInterface $conn) {} function onClose(ConnectionInterface $conn) {} function onError(ConnectionInterface $conn, Exception $e) {} function onMessage(ConnectionInterface $from, $msg) { $from->send($msg); } } $server = IoServer::factory( new HttpServer(new WsServer(new WS())), 3000 ); $server->run();
  • 44. The Web Application Messaging Protocol
  • 45. The Bigger The Better ➜ Remote Procedure Calls (RPC) ➜ Publish & Subscribe ➜ Autobahn.JS ➜ integracja ZeroMQ ➜ integracja Redis
  • 46. Autobahn.JS? // dla wersji AUTOBAHNJS_VERSION="0.7.1" var session = new ab.Session( "ws://127.0.0.1:3000", function () { // zostaliśmy połączeni }, function () { // zostaliśmy rozłączeni }, { 'skipSubprotocolCheck': true, 'maxRetries': 5, 'retryDelay': 2000 } ); session.subscribe("http://phpers.pl/event/message", callback);
  • 47. class WAMP implements RatchetWampWampServerInterface { public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) {} public function onCall(ConnectionInterface $conn, $id, $topic, array $params) {} public function onSubscribe(ConnectionInterface $conn, $topic) {} public function onUnSubscribe(ConnectionInterface $conn, $topic) {} public function onOpen(ConnectionInterface $conn) {} public function onClose(ConnectionInterface $conn) {} public function onError(ConnectionInterface $conn, Exception $e) {} } $server = RatchetServerIoServer::factory( new HttpServer(new WsServer(new WampServer(new WAMP()))), 3000 ); $server->run(); Ratchet + WAMP
  • 48. $loop = ReactEventLoopFactory::create(); $pusher = new WAMP; $context = new ReactZMQContext($loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://127.0.0.1:5555'); $pull->on('message', array($pusher, 'onQueueAdded')); $socket = new ReactSocketServer($loop); $socket->listen(3000, '0.0.0.0'); $webServer = new IoServer( new HttpServer(new WsServer(new WampServer($pusher))), $socket ); $loop->run(); ZeroMQ + Ratchet
  • 49. ZeroMQ + Ratchet $loop = ReactEventLoopFactory::create(); $pusher = new WAMP; $context = new ReactZMQContext($loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://127.0.0.1:5555'); $pull->on('message', array($pusher, 'onQueueAdded')); $socket = new ReactSocketServer($loop); $socket->listen(3000, '0.0.0.0'); $webServer = new IoServer( new HttpServer(new WsServer(new WampServer($pusher))), $socket ); $loop->run(); $context = new ZMQContext(); $socket = $context->getSocket( ZMQ::SOCKET_PUSH, 'websocket' ); $socket->connect('tcp://127.0.0.1:5555'); $socket->send($payloadAsJSON);
  • 50. ZeroMQ + Ratchet $loop = ReactEventLoopFactory::create(); $pusher = new WAMP; $context = new ReactZMQContext($loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://127.0.0.1:5555'); $pull->on('message', array($pusher, 'onQueueAdded')); $socket = new ReactSocketServer($loop); $socket->listen(3000, '0.0.0.0'); $webServer = new IoServer( new HttpServer(new WsServer(new WampServer($pusher))), $socket ); $loop->run(); $context = new ZMQContext(); $socket = $context->getSocket( ZMQ::SOCKET_PUSH, 'websocket' ); $socket->connect('tcp://127.0.0.1:5555'); $socket->send($payloadAsJSON); public function onQueueAdded($payload) { $payloadData = json_decode($payload, true); // dalsze przetwarzanie }
  • 51. MAO? ➜ WAMP2 ➜ voryx/Thruway (kompatybilny z nowym Autobahn.JS) ➜ bixuehujin/reactphp-mysql ➜ DNode ➜ STOMP ➜ AR.Drone ➜ Whois ➜ Childprocess
  • 53. Odniesienia i inspiracje ➜ http://blog.wyrihaximus.net/categories/reactphp/ ➜ Presentation theme - SlidesCarnival ➜ Zdjęcia - Death to the Stock Photo ➜ http://www.slideshare. net/SteveRhoades2/asynchronous-php-and-realtime- messaging ➜ https://speakerdeck.com/jmikola/async-php-with-react ➜ https://speakerdeck.com/igorw/react-phpnw