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

D1b6700884ac0ae368918ad171bb6a75?s=128

Christian Lück

April 13, 2018
Tweet

Transcript

  1. getting started with ReactPHP pushing real time data to the

    browser
  2. Agenda - Hello! - Introduction to async PHP with ReactPHP

    2
  3. Agenda - Hello! - Introduction to async PHP with ReactPHP

    - event loops 3
  4. Agenda - Hello! - Introduction to async PHP with ReactPHP

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

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

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

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

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

    - event loops - streaming data - sockets - promises - real time data - Streaming HTTP - Chat bots 9
  10. 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
  11. 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
  12. 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
  13. really? 13

  14. this is YOUR workshop 14

  15. you need: Composer + wifi 15

  16. I encourage feedback, questions + suggestions 16

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

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

    - event loops - streaming data - sockets - promises - event-driven, streaming application development - Conclusions 18
  19. Hello! 19

  20. $ whoami 20

  21. $ whoami Christian Lück 21

  22. $ whoami Christian Lück 22

  23. $ whoami Christian Lueck 23

  24. $ whoami Christian Lueck 24

  25. $ whoami Christian Lueck @clue 25

  26. $ whoami Christian Lueck @another_clue 26

  27. $ whoami Christian Lueck @another_clue passionate about pushing the limits

    27
  28. $ whoami Christian Lueck @another_clue passionate about pushing the limits

    freelance software engineer 28
  29. Who are you? 29 now that you know me…

  30. Who are you? 30 now that you know me… -

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

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

  33. The other React™ 33

  34. The REAL React™ 34

  35. PHP, the web of the ‘90s? 35

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

    stack - Request-Response-Cycle - PHP is too slow? 36 Apache Client PHP MySQL
  37. 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
  38. 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
  39. 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
  40. 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
  41. PHP may not be pretty… 41

  42. PHP may not be pretty… but it gets the job

    done! 42
  43. Knock knock! Who’s there? 43

  44. Knock knock! 2018! Who’s there? 44

  45. Knock knock! 2018! - Separation of concerns (Frontend↔Backend) - HTTP

    APIs (RESTful) - Integration with 3rd parties - Live-Data (ticker) - CLI tools Who’s there? 45
  46. nodejs? 46

  47. no js! 47

  48. Enter React! 48

  49. What is React? 49

  50. What is React? non-blocking I/O 50

  51. What is React? non-blocking I/O event-driven 51

  52. What is React? non-blocking I/O event-driven async 52

  53. 100% 53

  54. 100% pure PHP 54

  55. 100% pure PHP no extensions 55

  56. 100% pure PHP no extensions no magic 56

  57. What does that even mean?! 57

  58. the idea 58

  59. the idea calculations are fast 59

  60. the idea calculations are fast I/O is slow 60

  61. I/O is everywhere 61

  62. I/O is everywhere third party HTTP APIs (RESTful, SOAP, you

    name it…) 62
  63. I/O is everywhere third party HTTP APIs (RESTful, SOAP, you

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

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

    name it…) mysql, postgres filesystem I/O (session files) redis, memcache 65
  66. 66 Source: Latency Numbers Every Programmer Should Know: https://gist.github.com/jboner/2841832 CPU

    vs I/O
  67. I/O is slow! 67

  68. I/O is slow! So why wait? 68

  69. This is React 69

  70. This is React 70 Start multiple I/O operations (non-blocking)

  71. This is React 71 Start multiple I/O operations (non-blocking) Get

    notified when something happens (react)
  72. This is React 72 Start multiple I/O operations (non-blocking) Get

    notified when something happens (react) Don’t waste time waiting
  73. What React is not 73

  74. What React is not React is not black magic /

    vodoo 74
  75. What React is not React is not black magic /

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

    vodoo React is not a framework React is not the new buzz 76
  77. React core components 77

  78. event loops 78

  79. Event loop Consumers - THE core, low-level component 79

  80. 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
  81. 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();
  82. Event loop Implementors - Reactor pattern (hence the name) 82

  83. 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’; });
  84. 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);
  85. 85

  86. streaming data 86

  87. 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
  88. Streams - interfaces, events and listeners: 88 $dest->write(‘hello’); $source->on(‘data’, function

    ($data) { var_dump($data); }); $source->on(‘close’, function () { echo ‘stream closed’; });
  89. 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);
  90. 90

  91. sockets 91

  92. Sockets 92 - Streams, but over the network

  93. Sockets 93 - Streams, but over the network - servers

    listen - clients connect
  94. Sockets 94 - Streams, but over the network - servers

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

  96. Sockets in practice 96

  97. Sockets in practice - implementation detail 97

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

    (HTTP anybody) 98
  99. Sockets in practice - implementation detail - higher level protocols

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

    (HTTP anybody) - higher level concepts (RESTful etc.) - higher level APIs (SDKs, API clients etc.) 100
  101. 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
  102. promises 102

  103. Promises - Placeholder for a single future result - Possible

    states: - pending - fulfilled (successfully resolved) - rejected (Exception occured) 103
  104. 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’);
  105. Promises in practice - Everywhere! - react/socket - clue/buzz-react -

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

  107. HTTP streaming 107

  108. 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?
  109. EventSource 109

  110. Server-Sent Events (SSE) / EventSource 110

  111. Server-Sent Events in a gist 111 - Normal Request/Response -

    Client API for streaming access
  112. 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
  113. 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
  114. 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
  115. 115

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

    aka. EventSource (browser API) - Streaming events to browser - limited browser support 116
  117. WebSocket 117

  118. WebSocket 118 - HTTP Upgrade - Binary protocol - Bidirectional

    communication - Do you need this?
  119. Websocket server cboden/ratchet - Async WebSocket server - bidirectional data

    flow between browser and server - better browser support 119
  120. GUIs 120

  121. Zenity clue/zenity-react - PHP desktop GUI applications - very simple,

    Promise-based 121
  122. 122

  123. many, MANY more third-party projects: https://github.com/reactphp/react/wiki/Users 123

  124. Conclusions 124

  125. PHP 125

  126. PHP faster than you probably thought 126

  127. PHP faster than you probably thought more versatile than you

    probably thought 127
  128. ReactPHP 128

  129. ReactPHP 129 a real deal and here to stay

  130. ReactPHP 130 a real deal and here to stay stable

    & production ready
  131. ReactPHP 131 a real deal and here to stay stable

    & production ready *awesome*
  132. try! 132

  133. try! whenever having to wait 133

  134. try! whenever having to wait whenever accessing network 134

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

    - check open issues 135
  136. Need help? Want to help? - check each component’s README

    - check open issues - join #reactphp on irc.freenode.org - tweet @ReactPHP or #reactphp 136
  137. 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
  138. 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
  139. // thank you! $loop->stop(); 139 @another_clue – https://lueck.tv/

  140. Avoid blocking! - The loop must not be blocked 140

  141. Avoid blocking! - The loop must not be blocked -

    Many functions / lib assume blocking by default - Anything >1ms should be reconsidered 141
  142. 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
  143. 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
  144. 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
  145. Integration with traditional environments 145 integrating async into sync is

    easy
  146. Integration with traditional environments 146 integrating async into sync is

    easy - just run the loop until you’re done - see clue/block-react
  147. 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
  148. 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