ReactPHP is a set of packages, which allows writing asynchronous PHP. Machine operations are over 100x faster than I/O operations. ReactPHP wins in performance by not waiting for I/O operations to finish, it will run “the next code” instead. ReactPHP works faster because it will use your thread in the most efficient way. In this article, I tell you more about it.
Do not confuse this with parallel programming, were a new thread is opened when your original thread is blocked by an I/O operation. Parallel programming introduces problems like isolation, thread safety and slow context switching. Most importantly, the program becomes unnecessary complex.
PHP web applications already work parallel, there is a new thread opened for every connection. This way user A is never blocked by operations of user B. ReactPHP can be an improvement to this model, we still keep one thread for every user, but ReactPHP will use this thread at maximum capacity.
This article covers some basic concepts to understand how ReactPHP packages work. Make sure to read until the end, in the last paragraph we will set up a performant websocket server, which is designed to run forever.
“In ReactPHP everything runs asynchronous, except your code.”
This might look like an odd statement, since the previous paragraph said that ReactPHP runs asynchronous. Let me explain how this simple script is interpreted:
Program steps:
In step2 events are registered (in this example time events), in the next steps we will check which events are registered and whether one of them is triggered. The mentioned steps all run synchronously, but there is more to it. We have to zoom in on the “Eventloop” to understand why ReactPHP works asynchronously:
Eventloop steps:
The loop in the code above might run 100x times, but it will only print data after 1 and after 2 seconds. Note that the order of the events does not matter; the event after 1 second will run first, although the event after 2 seconds is defined first. This is why ReactPHP runs asynchronously.
This concept is the same for I/O operations, it does not matter when the operation starts, ReactPHP will only interact with it when it has something (data) to provide.
The check for exceeded timer events is only one step of the event loop, step two would be polling for I/O operations. This is a check to look if one of the earlier registered I/O operations has any results ready. An I/O operation can be many things: operations on a file, database operations, API-calls, printer commands, … And many more!
Almost all I/O operations correspond on the lowest level to streams, an important building block in the ReactPHP library.
In this example, we see 3 important streams:
With these two basic concepts, you should have a fond understanding of how the ReactPHP packages work. There are more basic concepts, if you are interested make sure to watch my conference video:
To understand websockets better, we first need to have a look at a regular HTTPS-connection. When a client would browse to blog.easi.net, this is what the HTTPS-handshake looks like:
As you may note, there is some overhead before the connection is established and closed. This overhead is not wrong when you ask a whole website from the server. Another important detail, the server cannot initiate a connection with the client. The client needs to start with a request (blog.easi.net).
The most popular use-case for web sockets is a user-to-user chat. Imagine two users would want to have a chat-conversation with each other (let’s say Bob and Alice). Our HTTPS-model would cause two big problems:
This is a use-case where websockets come in handy; a websocket-connection will stay open between client and server. The connection diagram will stay the same, only step 7 & 8 will not execute. Since the connection stays open, the handshake should only happen twice (once for Bob, once for Alice).
By using websockets we win time, bandwidth and most important: it will increase the user experience. Bob will receive Alice’s messages instantly and vice versa.
In ReactPHP we could set up such a (websocket-)chat-server in 22 lines of code:
There are 3 important objects to understand in this code sample:
Except for the mentioned three objects, there is nothing new in this script. There are two events registered which define how our server should react:
ReactPHP is a powerful tool, which can increase the performance and reactivity of your application. ReactPHP can be used as a standalone project, or the packages can be installed/added into your existing project/framework.
It is encouraged to use ReactPHP for long-running tasks or tasks which require many I/O operations. It can be a great alternative for Node.js/Go, especially if you know PHP already and the other technologies would be new for you.