Getting started with ReactPHP
Cees-Jan Kiewiet
- @WyriHaximus
- ReactPHP Team member
- Sculpin Team member
- Lead Software Engineer at
What is ReactPHP
Building a sample app:
- Analyzes hostnames
- Looks up IP address
- Fetches page title
- Fetches GeoIP
Demo time!
Requirements
- react/event-loop
- react/dns
- react/http
- react/filesystem
- wyrihaximus/react-guzzle-psr7
- clue/sse-react
- reactjs
https://github.com/WyriHaximus/reactphp-reactjs-hostname-analyzer-example
The Event Loop
The Heart of asynchronous code
Streams
Timers
Ticks
Loop creation
$loop = React\EventLoop\Factory::create();
$loop->run();
Available loops
- StreamSelectLoop
- LibEventLoop
- LibEvLoop
- ExtEventLoop
HTTP Server
Listens for incoming requests
Requests
Not
Connections
Creating the HTTP Server
$socket = new SocketServer($loop);
Creating the HTTP Server
$http = new HttpServer($socket, $loop);
Creating the HTTP Server
$http->on(
'request',
function ($request, $response) {
// Handle Request
}
);
Creating the HTTP Server
$socket->listen(2406);
SSE listener
if ($request->getPath() !== '/sse') {
return;
}
SSE listener
$response->writeHead(
200,
['Content-Type' =>
'text/event-stream']
);
SSE listener
$channel->connect($response);
$response->on('close', function () {
$channel->disconnect($response);
});
Broadcast listener
function broadcast($event)
{
$this->
channel->
writeMessage(
json_encode($event->data())
);
}
Lookup listener
if ($request->getPath() !==
'/lookup.json') {
return;
}
lookUp('php.net');
$response->writeHead(200);
$response->end('{}');
Filesystem
Evented filesystem access
Promises
Streams
Threads
Set up
$files = Filesystem::create($loop);
Set up
$files = Filesystem::create($loop)
->dir('/var/www/app/public');
Set up
$files = Filesystem::create($loop)
->dir('/var/www/app/public')
->lsRecursive();
Request listener
foreach ($listing as $node) {
if (!($node instanceof FileInterface)) {
continue;
}
}
Request listener
if ($request->getPath() ==
$node->getPath()) {
$response->writeHead(200);
$node->pipe($response);
}
DNS Resolver
Resolves DNS records by hostname
Hostnames
Cache
Promises
Creating the resolver
use React\Dns\Resolver\Factory;
$factory = new ResolverFactory();
Creating the resolver
$resolver = $factory->
createCached('8.8.8.8', $loop);
Looking up the IP
$resolver->resolve('php.net');
Looking up the IP
resolve()->then(function ($ip) {
broadcast([
'type' => 'ip',
'data' => $ip,
]);
});
HTTP Client
Basic HTTP 1.0 client
Streaming
Responses
Explicit
Setting up the HTTP client
$httpClient = new Client([
'handler' => new Adapter(
$loop,
null,
$dns
),
]);
GeoIP lookup
$httpClient->getAsync(
'https://freegeoip.net/json/php.net'
)
GeoIP lookup
getAsync()->then(function ($response) {
$body = $response->
getBody()->getContents();
broadcast([
'type' => 'geoip',
'data' => json_decode($body),
]);
}
Title lookup
$httpClient->getAsync('http://php.net');
Title lookup
getAsync()->then(function ($response) {
$body = $response->
getBody()->
getContents();
if (hasTitle($body)) {
broadcast([
'type' => 'title',
'data' => getTitle($body),
]);
}
});
Questions?
Github/Twitter: @WyriHaximus/@WyriHaximus
Rate my talk please: https://joind.in/talk/b625e
Slides: https://slides.com/wyrihaximus/getting-started-with-reactphp-dpc-2016
Code: https://github.com/WyriHaximus/reactphp-reactjs-hostname-analyzer-example
Blog: https://blog.wyrihaximus.net/categories/reactphp-series/
Getting started with ReactPHP (DPC 2016)
By wyrihaximus
Getting started with ReactPHP (DPC 2016)
- 2,377