https://github.com/WyriHaximus/cakephp-reactphp-cakefest2016
<?php
use React\EventLoop\Factory;
require 'vendor/autoload.php';
$loop = Factory::create();
$loop->run();
$socket = new SocketServer($loop);
$http = new HttpServer($socket, $loop);
$http->on('request', function (Request $request, Response $response) {
EventManager::instance()->dispatch(RequestEvent::create($request, $response));
});
$socket->listen(1337);
public function request(RequestEvent $event)
{
if ($event->getRequest()->getPath() !== '/sse') {
return;
}
$event->getResponse()->writeHead(
200,
['Content-Type' => 'text/event-stream')
);
$this->channel->connect($event->getResponse());
$event->getResponse()->on('close', function () use ($event) {
$this->channel->disconnect($event->getResponse());
});
$event->stopPropagation();
}
public function broadcast(BroadcastEvent $event)
{
$this->channel->writeMessage(json_encode($event->data()));
}
public function request(RequestEvent $event)
{
if ($event->getRequest()->getPath() == '/lookup.json') {
EventManager::instance()->dispatch(
LookupEvent::create($event->getRequest()->getQuery()['host'])
);
$event->getResponse()->writeHead(200);
$event->getResponse()->end('{}');
$event->stopPropagation();
}
}
public function __construct(LoopInterface $loop)
{
$this->files = Filesystem::create($loop)
->dir(ROOT . DS . App::path('webroot', 'WyriHaximus/CakeFest2016')[0])
->lsRecursive();
}
public function request(RequestEvent $event)
{
$this->files->then(function (SplObjectStorage $listing) use ($event) {
foreach ($listing as $node) {
if (!($node instanceof FileInterface)) {
continue;
}
if ($event->getRequest()->getPath() == $node->getPath()) {
$node->getContents()->then(function ($contents) use ($event) {
$event->getResponse()->writeHead(200);
$event->getResponse()->end($contents);
});
$event->stopPropagation();
}
}
});
}
<?php
use React\Dns\Resolver\Factory as ResolverFactory;
$resolver = (new ResolverFactory())->createCached('8.8.8.8', $loop);
public function lookup(LookupEvent $event)
{
$this->resolver->resolve($event->getHostname())->then(function ($ip) {
EventManager::instance()->dispatch(BroadcastEvent::create([
'type' => 'ip',
'data' => $ip,
]));
});
}
use GuzzleHttp\Client;
use WyriHaximus\React\GuzzlePsr7\HttpClientAdapter;
$httpClient = new Client([
'handler' => new HttpClientAdapter($loop, null, $dns),
]);
public function lookup(LookupEvent $event)
{
$this->httpClient->getAsync(
'https://freegeoip.net/json/' . $event->getHostname()
)->then(function (ResponseInterface $response) {
EventManager::instance()->dispatch(BroadcastEvent::create([
'type' => 'geoip',
'data' => json_decode($response->getBody()->getContents()),
]));
});
}
public function request(LookupEvent $event)
{
$this->httpClient->getAsync('http://' . $event->getHostname())
->then(function (ResponseInterface $response) {
if (preg_match(
'/<title>(.+)<\/title>/',
$response->getBody()->getContents(),
$matches
) && isset($matches[1])) {
EventManager::instance()->dispatch(BroadcastEvent::create([
'type' => 'title',
'data' => $matches[1],
]));
return;
}
EventManager::instance()->dispatch(BroadcastEvent::create([
'type' => 'title',
'data' => 'NO TITLE FOUND',
]));
});
}
Github/Twitter: @WyriHaximus/@WyriHaximus
Rate my talk please: https://joind.in/talk/3a76e
Slides: https://slides.com/wyrihaximus/getting-started-with-reactphp-cakfest-2016
Code: https://github.com/WyriHaximus/cakephp-reactphp-cakefest2016
Blog: https://blog.wyrihaximus.net/categories/reactphp-series/