Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting started with ReactPHP – Pushing real-time data to the browser (PHPYorkshire)

Getting started with ReactPHP – Pushing real-time data to the browser (PHPYorkshire)

Think about "PHP" for a few seconds… What came to mind? It’s very likely you thought about your average product catalog, a blogging platform or how the platform is inferior to things like Node.js. But wait, it’s 2018! What if I told you PHP’s huge ecosystem has way more to offer and PHP is not inferior at all to its evil cousin Node.js?

In this hands-on tutorial you will learn about the core concepts of async PHP and why you too should care about ReactPHP being a real thing. The workshop has a strong focus on sparking the idea that PHP can be way faster and more versatile than you probably thought. Bring along an open mind and through lots of interesting examples and live demos learn why what sounds crazy at first might soon be a valuable addition in your toolbox.

You’re already familiar with PHP and want to learn what ReactPHP is all about? Then this tutorial is for you! We will start from scratch and build a demo application that pushes data from your command line in real-time to your browser. Several scenarios are prepared, but ideally you bring in your own ideas: Let’s build an interactive chat bot, an interactive CLI tool or even an actual desktop GUI, it’s up to you!

The tutorial assumes people are familiar with PHP, have PHP and their favorite IDE already setup, but does not require people to be familiar with ReactPHP.

---

These slides were used as part of a hands-on workshop at @PHPYorkshire. The full workshop took 3h with basic project setup, getting started with ReactPHP's core components and eventually implementing an HTTP server using Server-Sent Events (EventSource).

Resulting source code can be found here: https://gist.github.com/clue/6ba091ed298b1ecec528a3a6c201a2d1

Christian Lück

April 13, 2018
Tweet

More Decks by Christian Lück

Other Decks in Programming

Transcript

  1. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets 5
  2. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises 6
  3. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data 7
  4. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP 8
  5. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP - Chat bots 9
  6. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP - Chat bots - interactive CLI tools 10
  7. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP - Chat bots - interactive CLI tools - desktop GUI 11
  8. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP - Chat bots - interactive CLI tools - desktop GUI - Conclusions 12
  9. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises 17
  10. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops - streaming data - sockets - promises - event-driven, streaming application development - Conclusions 18
  11. Who are you? 30 now that you know me… -

    PHP developers? - architecs / engineers?
  12. Who are you? 31 now that you know me… -

    PHP developers? - architecs / engineers? - know React?
  13. 32

  14. PHP and the web of the ‘90s - traditional LAMP

    stack - Request-Response-Cycle - PHP is too slow? 36 Apache Client PHP MySQL
  15. PHP and the web of the ‘90s - traditional LAMP

    stack - Request-Response-Cycle - PHP is too slow? - We sure can improve this… 37 Apache Client PHP MySQL
  16. PHP and the web of the ‘90s - traditional LAMP

    stack - Request-Response-Cycle - PHP is too slow? - We sure can improve this… 38 Apache Client PHP MySQL Apache Client FPM MySQL PHP PHP
  17. PHP and the web of the ‘90s - traditional LAMP

    stack - Request-Response-Cycle - PHP is too slow? - We sure can improve this… 39 Apache Client PHP MySQL Apache Client FPM MySQL PHP PHP nginx Client FPM MySQL PHP PHP
  18. PHP and the web of the ‘90s - traditional LAMP

    stack - Request-Response-Cycle - PHP is too slow? - We sure can improve this… 40 Apache Client PHP MySQL Apache Client FPM MySQL PHP PHP nginx Client FPM MySQL PHP PHP nginx Client FPM memcache PHP PHP MySQL
  19. Knock knock! 2018! - Separation of concerns (Frontend↔Backend) - HTTP

    APIs (RESTful) - Integration with 3rd parties - Live-Data (ticker) - CLI tools Who’s there? 45
  20. I/O is everywhere third party HTTP APIs (RESTful, SOAP, you

    name it…) mysql, postgres filesystem I/O (session files) 64
  21. I/O is everywhere third party HTTP APIs (RESTful, SOAP, you

    name it…) mysql, postgres filesystem I/O (session files) redis, memcache 65
  22. This is React 72 Start multiple I/O operations (non-blocking) Get

    notified when something happens (react) Don’t waste time waiting
  23. What React is not React is not black magic /

    vodoo React is not a framework 75
  24. What React is not React is not black magic /

    vodoo React is not a framework React is not the new buzz 76
  25. Event loop Consumers - THE core, low-level component - Create

    an instance - Just use the Factory - Additional extensions for bigger payloads - something inbetween… - just pass the $loop around - Start running - keeps running forever - unless stopped or done 80
  26. Event loop Consumers - THE core, low-level component - Create

    an instance - Just use the Factory - Additional extensions for bigger payloads - something inbetween… - just pass the $loop around - Start running - keeps running forever - unless stopped or done 81 $loop = Factory::create(); // something inbetween // pass the $loop around to all components $loop->run();
  27. Event loop Implementors - Reactor pattern (hence the name) -

    start timers - once - periodic - ticks 83 $loop->addTimer(0.5, function () { echo ‘world’; }); $loop->addTimer(0.3, function () { echo ‘hello’; });
  28. Event loop Implementors - Reactor pattern (hence the name) -

    start timers - once - periodic - ticks - wait for stream resources to become - readable - writable 84 $loop->addTimer(0.5, function () { echo ‘world’; }); $loop->addTimer(0.3, function () { echo ‘hello’; }); $loop->addReadStream($stream, $fn); $loop->addWriteStream($stream, $fn);
  29. 85

  30. Streams - Process large strings in chunks as they happen

    (think downloads) - Types - Readable (e.g. STDIN pipe) - Writable (e.g. STDOUT pipe) - Duplex (e.g. TCP/IP connection) 87
  31. Streams - interfaces, events and listeners: 88 $dest->write(‘hello’); $source->on(‘data’, function

    ($data) { var_dump($data); }); $source->on(‘close’, function () { echo ‘stream closed’; });
  32. Streams - interfaces, events and listeners: 89 $dest->write(‘hello’); $source->on(‘data’, function

    ($data) { var_dump($data); }); $source->on(‘close’, function () { echo ‘stream closed’; }); $source->pipe($gunzip)->pipe($badwords)->pipe($dest);
  33. 90

  34. Sockets 94 - Streams, but over the network - servers

    listen - clients connect - Focus on TCP/IP (UDP etc. also possible)
  35. 95

  36. Sockets in practice - implementation detail - higher level protocols

    (HTTP anybody) - higher level concepts (RESTful etc.) 99
  37. Sockets in practice - implementation detail - higher level protocols

    (HTTP anybody) - higher level concepts (RESTful etc.) - higher level APIs (SDKs, API clients etc.) 100
  38. Sockets in practice - implementation detail - higher level protocols

    (HTTP anybody) - higher level concepts (RESTful etc.) - higher level APIs (SDKs, API clients etc.) - Concepts still apply, details are hidden 101
  39. Promises - Placeholder for a single future result - Possible

    states: - pending - fulfilled (successfully resolved) - rejected (Exception occured) 103
  40. Promises - no more imperative code flow - instead (tell,

    don’t ask) 104 $a->then($fulfilled = null, $rejected = null); $a->then(‘process’); $a->then(‘process’, ‘var_dump’);
  41. Promises in practice - Everywhere! - react/socket - clue/buzz-react -

    clue/packagist-react - clue/redis-react - react/mysql 105
  42. 106

  43. HTTP streaming 108 - HTTP request/response semantics - streaming responses

    (download huge files) - streaming requests (upload huge files) - Still request/response semantics - Long-polling (Comet) anyone?
  44. Server-Sent Events in a gist 112 - Normal Request/Response -

    Client API for streaming access HTTP/1.1 200 OK Content-Type: text/event-stream
  45. Server-Sent Events in a gist 113 - Normal Request/Response -

    Client API for streaming access HTTP/1.1 200 OK Content-Type: text/event-stream data: hello
  46. Server-Sent Events in a gist 114 - Normal Request/Response -

    Client API for streaming access HTTP/1.1 200 OK Content-Type: text/event-stream data: hello data: world
  47. 115

  48. Server sent events clue/sse-react - Server sent events (SSE) -

    aka. EventSource (browser API) - Streaming events to browser - limited browser support 116
  49. Websocket server cboden/ratchet - Async WebSocket server - bidirectional data

    flow between browser and server - better browser support 119
  50. 122

  51. Need help? Want to help? - check each component’s README

    - check open issues - join #reactphp on irc.freenode.org - tweet @ReactPHP or #reactphp 136
  52. Need help? Want to help? - check each component’s README

    - check open issues - join #reactphp on irc.freenode.org - tweet @ReactPHP or #reactphp - Talk to me 137
  53. Need help? Want to help? - check each component’s README

    - check open issues - join #reactphp on irc.freenode.org - tweet @ReactPHP or #reactphp - Talk to me Did I mention I’m available? 138
  54. Avoid blocking! - The loop must not be blocked -

    Many functions / lib assume blocking by default - Anything >1ms should be reconsidered 141
  55. Avoid blocking! - The loop must not be blocked -

    Many functions / lib assume blocking by default - Anything >1ms should be reconsidered - Alternatives - Single result: Promises - Evented: Streams 142
  56. Avoid blocking! - The loop must not be blocked -

    Many functions / lib assume blocking by default - Anything >1ms should be reconsidered - Alternatives - Single result: Promises - Evented: Streams - Need a blocking function? - Fork off! - Use IPC 143
  57. Avoid blocking! - The loop must not be blocked -

    Many functions / lib assume blocking by default - Anything >1ms should be reconsidered - Alternatives - Single result: Promises - Evented: Streams - Need a blocking function? - Fork off! - Use IPC 144 Pay attention: - PDO, mysql etc. - file system access - network access - third-party APIs
  58. Integration with traditional environments 146 integrating async into sync is

    easy - just run the loop until you’re done - see clue/block-react
  59. Integration with traditional environments 147 integrating async into sync is

    easy - just run the loop until you’re done - see clue/block-react integrating sync into async is hard
  60. Integration with traditional environments 148 integrating async into sync is

    easy - just run the loop until you’re done - see clue/block-react integrating sync into async is hard - often requires async rewrite - consider forking instead