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

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

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 2020! 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 talk you will learn about the core concepts of async PHP and why you too should care about ReactPHP being a real thing. The talk 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 talk is for you! We will start from scratch and see what it takes to build an application that pushes data from your command line to your browser in real-time. You’re invited to join the interactive demos or lean back and learn more about why an event-driven approach might be the next big thing in making your application faster and more responsive.

---

These slides were used as part of a presentation at @phpbenelux. The full presentation took 60min 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/c426bcee9c7767157085d6b881204998

D1b6700884ac0ae368918ad171bb6a75?s=128

Christian Lück

January 25, 2020
Tweet

Transcript

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

    @another_clue
  2. @another_clue Agenda - Hello! - Introduction to async PHP with

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

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

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

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

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

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

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

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

  14. @another_clue this is a getting started guide 14

  15. @another_clue pushing real-time data to the browser 15

  16. @another_clue I encourage feedback, questions + suggestions 16

  17. @another_clue Agenda - Hello! - Introduction to async PHP with

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

    ReactPHP - event loops - streaming data - sockets - promises - conclusions 18 examples and demo time!
  19. @another_clue Hello! 19

  20. @another_clue $ whoami 20

  21. @another_clue $ whoami Christian Lück 21

  22. @another_clue $ whoami Christian Lück 22

  23. @another_clue $ whoami Christian Lueck 23

  24. @another_clue $ whoami Christian Lueck 24

  25. @another_clue $ whoami Christian Lueck @clue 25

  26. @another_clue $ whoami Christian Lueck @another_clue 26

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

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

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

  30. @another_clue Who are you? 30 now that you know me…

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

    - PHP developers? - architecs / engineers? - know React?
  32. @another_clue PHP, the web of the ‘90s? 32

  33. @another_clue PHP and the web of the ‘90s 33

  34. @another_clue PHP and the web of the ‘90s 34 Apache

    Client PHP MySQL
  35. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack 35 Apache Client PHP MySQL
  36. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack Request-Response-Cycle 36 Apache Client PHP MySQL
  37. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack Request-Response-Cycle PHP is too slow? 37 Apache Client PHP MySQL
  38. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack Request-Response-Cycle PHP is too slow? 38 Apache Client MySQL FPM PHP PHP
  39. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack Request-Response-Cycle PHP is too slow? 39 nginx Client MySQL FPM PHP PHP
  40. @another_clue PHP and the web of the ‘90s traditional LAMP

    stack Request-Response-Cycle PHP is too slow? 40 nginx Client FPM PHP PHP memcache MySQL
  41. @another_clue PHP may not be pretty… 41

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

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

  44. @another_clue Knock knock! 2020! Who’s there? 44

  45. @another_clue Knock knock! 2020! - Separation of concerns (Frontend↔Backend) -

    HTTP APIs (RESTful) - Integration with 3rd parties - Live-Data (ticker) - CLI tools Who’s there? 45
  46. @another_clue Knock knock! 2020! - Separation of concerns (Frontend↔Backend) -

    HTTP APIs (RESTful) - Integration with 3rd parties - Live-Data (ticker) - CLI tools Who’s there? 46
  47. @another_clue Node.js 47

  48. @another_clue Node.js 48 good fit, huge ecosystem

  49. @another_clue Node.js 49 good fit, huge ecosystem interesting concepts

  50. @another_clue Node.js 50 good fit, huge ecosystem interesting concepts npm

    install…
  51. @another_clue nodejs? 51

  52. @another_clue no js! 52

  53. @another_clue Everybody’s favorite language… 53

  54. @another_clue PHP 54

  55. @another_clue PHP 55 gets the job done

  56. @another_clue PHP 56 gets the job done widespread usage

  57. @another_clue PHP 57 gets the job done widespread usage if

    PHP can do it…
  58. @another_clue Enter React! 58

  59. @another_clue 59

  60. @another_clue The other React™ 60

  61. @another_clue The REAL React™ 61

  62. @another_clue 62

  63. @another_clue What is React? 63

  64. @another_clue What is React? non-blocking I/O 64

  65. @another_clue What is React? non-blocking I/O event-driven 65

  66. @another_clue What is React? non-blocking I/O event-driven async 66

  67. @another_clue 100% 67

  68. @another_clue 100% pure PHP 68

  69. @another_clue 100% pure PHP no extensions 69

  70. @another_clue 100% pure PHP no extensions no magic 70

  71. @another_clue What does that even mean?! 71

  72. @another_clue the idea 72

  73. @another_clue calculations are fast 73 the idea

  74. @another_clue calculations are fast I/O is slow 74 the idea

  75. @another_clue 75 Source: Latency Numbers Every Programmer Should Know: https://gist.github.com/jboner/2841832

    CPU vs I/O
  76. @another_clue I/O is everywhere 76

  77. @another_clue I/O is everywhere third party HTTP APIs (RESTful, SOAP,

    you name it…) 77
  78. @another_clue I/O is everywhere third party HTTP APIs (RESTful, SOAP,

    you name it…) mysql, postgres 78
  79. @another_clue I/O is everywhere third party HTTP APIs (RESTful, SOAP,

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

    you name it…) mysql, postgres filesystem I/O (session files) redis, memcache 80
  81. @another_clue I/O is slow! 81

  82. @another_clue I/O is slow! So why wait? 82

  83. @another_clue This is React 83

  84. @another_clue This is React 84 Start multiple I/O operations (non-blocking)

  85. @another_clue This is React 85 Start multiple I/O operations (non-blocking)

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

    Get notified when something happens (react) Don’t waste time waiting
  87. @another_clue What React is not 87

  88. @another_clue What React is not React is not black magic

    / vodoo 88
  89. @another_clue What React is not React is not black magic

    / vodoo React is not a framework 89
  90. @another_clue What React is not React is not black magic

    / vodoo React is not a framework React is not the new buzz 90
  91. @another_clue React core components 91

  92. @another_clue event loop 92

  93. @another_clue Event loop Consumers - THE core, low-level component 93

  94. @another_clue 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 94
  95. @another_clue 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 95
  96. @another_clue Event loop Implementors - Reactor pattern (hence the name)

    96
  97. @another_clue Event loop Implementors - Reactor pattern (hence the name)

    - start timers - once - periodic - ticks 97
  98. @another_clue Event loop Implementors - Reactor pattern (hence the name)

    - start timers - once - periodic - ticks 98
  99. @another_clue Event loop Implementors - Reactor pattern (hence the name)

    - start timers - once - periodic - ticks 99
  100. @another_clue Event loop Implementors - Reactor pattern (hence the name)

    - start timers - once - periodic - ticks - plus wait for stream resources to become - readable - writable 100
  101. @another_clue streaming data 101

  102. @another_clue 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) 102
  103. @another_clue Stream interfaces and events 103

  104. @another_clue Stream interfaces and events 104

  105. @another_clue Stream interfaces and events 105

  106. @another_clue sockets 106

  107. @another_clue Sockets 107 - Streams, but over the network

  108. @another_clue Sockets 108 - Streams, but over the network -

    servers listen - clients connect
  109. @another_clue Sockets 109 - Streams, but over the network -

    servers listen - clients connect - Focus on TCP/IP (UDP etc. also possible)
  110. @another_clue Sockets 110 - Streams, but over the network -

    servers listen - clients connect - Focus on TCP/IP (UDP etc. also possible)
  111. @another_clue Sockets 111 - Streams, but over the network -

    servers listen - clients connect - Focus on TCP/IP (UDP etc. also possible)
  112. @another_clue Sockets 112 - Streams, but over the network -

    servers listen - clients connect - Focus on TCP/IP (UDP etc. also possible)
  113. @another_clue Sockets in practice 113

  114. @another_clue Sockets in practice - implementation detail 114

  115. @another_clue Sockets in practice - implementation detail - higher level

    protocols (HTTP anybody) 115
  116. @another_clue Sockets in practice - implementation detail - higher level

    protocols (HTTP anybody) - higher level concepts (RESTful etc.) 116
  117. @another_clue Sockets in practice - implementation detail - higher level

    protocols (HTTP anybody) - higher level concepts (RESTful etc.) - higher level APIs (SDKs, API clients etc.) 117
  118. @another_clue 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 118
  119. @another_clue promises 119

  120. @another_clue Promises - Placeholder for a single future result -

    Possible states: - pending - fulfilled (successfully resolved) - rejected (Exception occured) 120
  121. @another_clue Promise API 121

  122. @another_clue Promise API 122

  123. @another_clue Promise API usage 123

  124. @another_clue Promise API usage 124

  125. @another_clue Promise API usage 125

  126. @another_clue Promises in practice - 126

  127. @another_clue Promises in practice - Everywhere! 127

  128. @another_clue Promises in practice - Everywhere! - react/socket - clue/buzz-react

    - clue/packagist-react - clue/redis-react - react/mysql - … 128
  129. @another_clue HTTP streaming 129

  130. @another_clue HTTP in a gist 130

  131. @another_clue HTTP in a gist 131 GET / HTTP/1.1

  132. @another_clue HTTP in a gist 132 GET / HTTP/1.1 HTTP/1.1

    200 OK Content-Type: text/plain hello world!
  133. @another_clue HTTP in a gist 133 GET / HTTP/1.1 HTTP/1.1

    200 OK Content-Type: text/plain hello world!
  134. @another_clue HTTP streaming 134

  135. @another_clue HTTP streaming 135 - HTTP request/response semantics

  136. @another_clue HTTP streaming 136 - HTTP request/response semantics - streaming

    responses (download huge files) - streaming requests (upload huge files)
  137. @another_clue HTTP streaming 137 - HTTP request/response semantics - streaming

    responses (download huge files) - streaming requests (upload huge files) - Still request/response semantics
  138. @another_clue HTTP streaming 138 - HTTP request/response semantics - streaming

    responses (download huge files) - streaming requests (upload huge files) - Still request/response semantics - Long-polling (Comet) anyone?
  139. @another_clue HTTP streaming 139 - HTTP request/response semantics - streaming

    responses (download huge files) - streaming requests (upload huge files) - Still request/response semantics - Long-polling (Comet) anyone?
  140. @another_clue EventSource 140

  141. @another_clue Server-Sent Events (SSE) / EventSource 141

  142. @another_clue Server-Sent Events in a gist 142 - Normal Request/Response

    - Client API for streaming access
  143. @another_clue Server-Sent Events in a gist 143 - Normal Request/Response

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

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

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

    - Client API for streaming access HTTP/1.1 200 OK Content-Type: text/event-stream data: hello data: world
  147. @another_clue fully-functional streaming HTTP server in a single PHP file

    147
  148. @another_clue PubSub 148

  149. @another_clue PubSub 149 - Publish/Subscribe

  150. @another_clue PubSub 150 - Publish/Subscribe - common pattern for distributed

    system
  151. @another_clue PubSub 151 - Publish/Subscribe - common pattern for distributed

    system - message broker in between
  152. @another_clue PubSub 152 - Publish/Subscribe - common pattern for distributed

    system - message broker in between Publisher Redis Subscriber
  153. @another_clue PubSub 153 - Publish/Subscribe - common pattern for distributed

    system - message broker in between - horizontal scalability - independent components Publisher Redis Subscriber
  154. @another_clue PubSub 154 - Publish/Subscribe - common pattern for distributed

    system - message broker in between - horizontal scalability - independent components Publisher Redis Subscriber Publisher Subscriber Publisher Subscriber
  155. @another_clue PubSub 155 - Publish/Subscribe - common pattern for distributed

    system - message broker in between - horizontal scalability - independent components Publisher Redis Subscriber Publisher Subscriber Publisher Subscriber
  156. @another_clue PubSub 156 - Publish/Subscribe - common pattern for distributed

    system - message broker in between - horizontal scalability - independent components Publisher Redis Subscriber Publisher Subscriber Publisher Subscriber
  157. @another_clue PubSub 157 - Publish/Subscribe - common pattern for distributed

    system - message broker in between - horizontal scalability - independent components Publisher Redis Subscriber Publisher Subscriber Publisher Subscriber
  158. @another_clue fully-functional, distributed HTTP streaming server in a single PHP

    file 158
  159. @another_clue many, MANY more third-party projects: https://github.com/reactphp/react/wiki/Users 159

  160. @another_clue Conclusions 160

  161. @another_clue 161 Can I use ReactPHP to make my website

    1000x faster?
  162. @another_clue YES 162 Can I use ReactPHP to make my

    website 1000x faster?
  163. @another_clue YES 163 But you might be missing the point…

    Can I use ReactPHP to make my website 1000x faster?
  164. @another_clue PHP 164

  165. @another_clue PHP faster than you probably thought 165

  166. @another_clue PHP faster than you probably thought more versatile than

    you probably thought 166
  167. @another_clue ReactPHP 167

  168. @another_clue ReactPHP 168 a real deal and here to stay

  169. @another_clue ReactPHP 169 a real deal and here to stay

    stable & production ready
  170. @another_clue ReactPHP 170 a real deal and here to stay

    stable & production ready *awesome*
  171. @another_clue try! 171

  172. @another_clue try! whenever having to wait 172

  173. @another_clue try! whenever having to wait whenever accessing network 173

  174. @another_clue help! 174

  175. @another_clue help! elaborate documentation on ReactPHP.org 175

  176. @another_clue help! elaborate documentation on ReactPHP.org tweet @ReactPHP or #reactphp

    176
  177. @another_clue help! elaborate documentation on ReactPHP.org tweet @ReactPHP or #reactphp

    Talk to me 177
  178. @another_clue help! elaborate documentation on ReactPHP.org tweet @ReactPHP or #reactphp

    Talk to me Did I mention I’m available? 178
  179. @another_clue // thank you! $loop->stop(); 179 @another_clue – https://clue.engineering/

  180. @another_clue integration 180

  181. @another_clue integration non-blocking and blocking don’t mix well 181

  182. @another_clue integration non-blocking and blocking don’t mix well decide for

    either approach 182
  183. @another_clue integration non-blocking and blocking don’t mix well decide for

    either approach isolate & communicate 183
  184. @another_clue Integration with traditional environments 184 integrating async into sync

    is easy
  185. @another_clue Integration with traditional environments 185 integrating async into sync

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

    is easy - just run the loop until you’re done - see clue/block-react integrating sync into async is hard
  187. @another_clue Integration with traditional environments 187 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
  188. @another_clue Avoid blocking! - The loop must not be blocked

    188
  189. @another_clue Avoid blocking! - The loop must not be blocked

    - Many functions / lib assume blocking by default - Anything >1ms should be reconsidered 189
  190. @another_clue 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 190
  191. @another_clue 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 191
  192. @another_clue 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 192 Pay attention: - PDO, mysql etc. - file system access - network access - third-party APIs